protocol_handler_registry_unittest.cc revision 0529e5d033099cbfc42635f6f6183833b09dff6e
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/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/base/request_priority.h" 25#include "net/url_request/url_request.h" 26#include "net/url_request/url_request_context.h" 27#include "testing/gtest/include/gtest/gtest.h" 28 29using content::BrowserThread; 30 31namespace { 32 33void AssertInterceptedIO( 34 const GURL& url, 35 net::URLRequestJobFactory* interceptor) { 36 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 37 net::URLRequestContext context; 38 net::URLRequest request(url, net::DEFAULT_PRIORITY, NULL, &context); 39 scoped_refptr<net::URLRequestJob> job = 40 interceptor->MaybeCreateJobWithProtocolHandler( 41 url.scheme(), &request, context.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() {} 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#if defined(OS_ANDROID) 294 case base::MessageLoop::TYPE_JAVA: // fall-through 295#endif // defined(OS_ANDROID) 296 case base::MessageLoop::TYPE_CUSTOM: 297 case base::MessageLoop::TYPE_DEFAULT: 298 return !BrowserThread::CurrentlyOn(BrowserThread::UI) && 299 !BrowserThread::CurrentlyOn(BrowserThread::IO); 300 } 301 return false; 302 } 303}; 304 305} // namespace 306 307class ProtocolHandlerRegistryTest : public testing::Test { 308 protected: 309 ProtocolHandlerRegistryTest() 310 : ui_thread_(BrowserThread::UI, &loop_), 311 file_thread_(BrowserThread::FILE, &loop_), 312 io_thread_(BrowserThread::IO, &loop_), 313 test_protocol_handler_(CreateProtocolHandler("test", "test")) {} 314 315 FakeDelegate* delegate() const { return delegate_; } 316 ProtocolHandlerRegistry* registry() { return registry_.get(); } 317 TestingProfile* profile() const { return profile_.get(); } 318 const ProtocolHandler& test_protocol_handler() const { 319 return test_protocol_handler_; 320 } 321 322 ProtocolHandler CreateProtocolHandler(const std::string& protocol, 323 const GURL& url, 324 const std::string& title) { 325 return ProtocolHandler::CreateProtocolHandler(protocol, url, 326 base::UTF8ToUTF16(title)); 327 } 328 329 ProtocolHandler CreateProtocolHandler(const std::string& protocol, 330 const std::string& name) { 331 return CreateProtocolHandler(protocol, GURL("http://" + name + "/%s"), 332 name); 333 } 334 335 void RecreateRegistry(bool initialize) { 336 TeadDownRegistry(); 337 SetUpRegistry(initialize); 338 } 339 340 // Returns a new registry, initializing it if |initialize| is true. 341 // Caller assumes ownership for the object 342 void SetUpRegistry(bool initialize) { 343 delegate_ = new FakeDelegate(); 344 registry_.reset(new ProtocolHandlerRegistry(profile(), delegate())); 345 if (initialize) registry_->InitProtocolSettings(); 346 } 347 348 void TeadDownRegistry() { 349 registry_->Shutdown(); 350 registry_.reset(); 351 // Registry owns the delegate_ it handles deletion of that object. 352 } 353 354 virtual void SetUp() { 355 profile_.reset(new TestingProfile()); 356 CHECK(profile_->GetPrefs()); 357 SetUpRegistry(true); 358 test_protocol_handler_ = 359 CreateProtocolHandler("test", GURL("http://test.com/%s"), "Test"); 360 } 361 362 virtual void TearDown() { 363 TeadDownRegistry(); 364 } 365 366 TestMessageLoop loop_; 367 368 private: 369 content::TestBrowserThread ui_thread_; 370 content::TestBrowserThread file_thread_; 371 content::TestBrowserThread io_thread_; 372 373 scoped_ptr<TestingProfile> profile_; 374 FakeDelegate* delegate_; // Registry assumes ownership of delegate_. 375 scoped_ptr<ProtocolHandlerRegistry> registry_; 376 ProtocolHandler test_protocol_handler_; 377}; 378 379// ProtocolHandlerRegistryTest tests are flaky on Linux & ChromeOS. 380// http://crbug.com/133023 381#if defined(OS_LINUX) 382#define MAYBE_AcceptProtocolHandlerHandlesProtocol \ 383 DISABLED_AcceptProtocolHandlerHandlesProtocol 384#define MAYBE_DeniedProtocolIsntHandledUntilAccepted \ 385 DISABLED_DeniedProtocolIsntHandledUntilAccepted 386#define MAYBE_TestStartsAsDefault DISABLED_TestStartsAsDefault 387#define MAYBE_TestRemoveHandlerRemovesDefault \ 388 DISABLED_TestRemoveHandlerRemovesDefault 389#define MAYBE_TestClearDefaultGetsPropagatedToIO \ 390 DISABLED_TestClearDefaultGetsPropagatedToIO 391#define MAYBE_TestIsHandledProtocolWorksOnIOThread \ 392 DISABLED_TestIsHandledProtocolWorksOnIOThread 393#define MAYBE_TestInstallDefaultHandler \ 394 DISABLED_TestInstallDefaultHandler 395#else 396#define MAYBE_AcceptProtocolHandlerHandlesProtocol \ 397 AcceptProtocolHandlerHandlesProtocol 398#define MAYBE_DeniedProtocolIsntHandledUntilAccepted \ 399 DeniedProtocolIsntHandledUntilAccepted 400#define MAYBE_TestStartsAsDefault TestStartsAsDefault 401#define MAYBE_TestRemoveHandlerRemovesDefault TestRemoveHandlerRemovesDefault 402#define MAYBE_TestClearDefaultGetsPropagatedToIO \ 403 TestClearDefaultGetsPropagatedToIO 404#define MAYBE_TestIsHandledProtocolWorksOnIOThread \ 405 TestIsHandledProtocolWorksOnIOThread 406#define MAYBE_TestInstallDefaultHandler TestInstallDefaultHandler 407#endif // defined(OS_LINUX) 408 409TEST_F(ProtocolHandlerRegistryTest, 410 MAYBE_AcceptProtocolHandlerHandlesProtocol) { 411 ASSERT_FALSE(registry()->IsHandledProtocol("test")); 412 registry()->OnAcceptRegisterProtocolHandler(test_protocol_handler()); 413 ASSERT_TRUE(registry()->IsHandledProtocol("test")); 414} 415 416TEST_F(ProtocolHandlerRegistryTest, 417 MAYBE_DeniedProtocolIsntHandledUntilAccepted) { 418 registry()->OnDenyRegisterProtocolHandler(test_protocol_handler()); 419 ASSERT_FALSE(registry()->IsHandledProtocol("test")); 420 registry()->OnAcceptRegisterProtocolHandler(test_protocol_handler()); 421 ASSERT_TRUE(registry()->IsHandledProtocol("test")); 422} 423 424TEST_F(ProtocolHandlerRegistryTest, ClearDefaultMakesProtocolNotHandled) { 425 registry()->OnAcceptRegisterProtocolHandler(test_protocol_handler()); 426 registry()->ClearDefault("test"); 427 ASSERT_FALSE(registry()->IsHandledProtocol("test")); 428 ASSERT_TRUE(registry()->GetHandlerFor("test").IsEmpty()); 429} 430 431TEST_F(ProtocolHandlerRegistryTest, DisableDeregistersProtocolHandlers) { 432 ASSERT_FALSE(delegate()->IsExternalHandlerRegistered("test")); 433 registry()->OnAcceptRegisterProtocolHandler(test_protocol_handler()); 434 ASSERT_TRUE(delegate()->IsExternalHandlerRegistered("test")); 435 436 registry()->Disable(); 437 ASSERT_FALSE(delegate()->IsExternalHandlerRegistered("test")); 438 registry()->Enable(); 439 ASSERT_TRUE(delegate()->IsExternalHandlerRegistered("test")); 440} 441 442TEST_F(ProtocolHandlerRegistryTest, IgnoreProtocolHandler) { 443 registry()->OnIgnoreRegisterProtocolHandler(test_protocol_handler()); 444 ASSERT_TRUE(registry()->IsIgnored(test_protocol_handler())); 445 446 registry()->RemoveIgnoredHandler(test_protocol_handler()); 447 ASSERT_FALSE(registry()->IsIgnored(test_protocol_handler())); 448} 449 450TEST_F(ProtocolHandlerRegistryTest, IgnoreEquivalentProtocolHandler) { 451 ProtocolHandler ph1 = CreateProtocolHandler("test", GURL("http://test/%s"), 452 "test1"); 453 ProtocolHandler ph2 = CreateProtocolHandler("test", GURL("http://test/%s"), 454 "test2"); 455 456 registry()->OnIgnoreRegisterProtocolHandler(ph1); 457 ASSERT_TRUE(registry()->IsIgnored(ph1)); 458 ASSERT_TRUE(registry()->HasIgnoredEquivalent(ph2)); 459 460 registry()->RemoveIgnoredHandler(ph1); 461 ASSERT_FALSE(registry()->IsIgnored(ph1)); 462 ASSERT_FALSE(registry()->HasIgnoredEquivalent(ph2)); 463} 464 465TEST_F(ProtocolHandlerRegistryTest, SaveAndLoad) { 466 ProtocolHandler stuff_protocol_handler( 467 CreateProtocolHandler("stuff", "stuff")); 468 registry()->OnAcceptRegisterProtocolHandler(test_protocol_handler()); 469 registry()->OnIgnoreRegisterProtocolHandler(stuff_protocol_handler); 470 471 ASSERT_TRUE(registry()->IsHandledProtocol("test")); 472 ASSERT_TRUE(registry()->IsIgnored(stuff_protocol_handler)); 473 delegate()->Reset(); 474 RecreateRegistry(true); 475 ASSERT_TRUE(registry()->IsHandledProtocol("test")); 476 ASSERT_TRUE(registry()->IsIgnored(stuff_protocol_handler)); 477} 478 479TEST_F(ProtocolHandlerRegistryTest, TestEnabledDisabled) { 480 registry()->Disable(); 481 ASSERT_FALSE(registry()->enabled()); 482 registry()->Enable(); 483 ASSERT_TRUE(registry()->enabled()); 484} 485 486TEST_F(ProtocolHandlerRegistryTest, 487 DisallowRegisteringExternallyHandledProtocols) { 488 delegate()->RegisterExternalHandler("test"); 489 ASSERT_FALSE(registry()->CanSchemeBeOverridden("test")); 490} 491 492TEST_F(ProtocolHandlerRegistryTest, RemovingHandlerMeansItCanBeAddedAgain) { 493 registry()->OnAcceptRegisterProtocolHandler(test_protocol_handler()); 494 ASSERT_TRUE(registry()->CanSchemeBeOverridden("test")); 495 registry()->RemoveHandler(test_protocol_handler()); 496 ASSERT_TRUE(registry()->CanSchemeBeOverridden("test")); 497} 498 499TEST_F(ProtocolHandlerRegistryTest, MAYBE_TestStartsAsDefault) { 500 registry()->OnAcceptRegisterProtocolHandler(test_protocol_handler()); 501 ASSERT_TRUE(registry()->IsDefault(test_protocol_handler())); 502} 503 504TEST_F(ProtocolHandlerRegistryTest, TestClearDefault) { 505 ProtocolHandler ph1 = CreateProtocolHandler("test", "test1"); 506 ProtocolHandler ph2 = CreateProtocolHandler("test", "test2"); 507 registry()->OnAcceptRegisterProtocolHandler(ph1); 508 registry()->OnAcceptRegisterProtocolHandler(ph2); 509 510 registry()->OnAcceptRegisterProtocolHandler(ph1); 511 registry()->ClearDefault("test"); 512 ASSERT_FALSE(registry()->IsDefault(ph1)); 513 ASSERT_FALSE(registry()->IsDefault(ph2)); 514} 515 516TEST_F(ProtocolHandlerRegistryTest, TestGetHandlerFor) { 517 ProtocolHandler ph1 = CreateProtocolHandler("test", "test1"); 518 ProtocolHandler ph2 = CreateProtocolHandler("test", "test2"); 519 registry()->OnAcceptRegisterProtocolHandler(ph1); 520 registry()->OnAcceptRegisterProtocolHandler(ph2); 521 522 registry()->OnAcceptRegisterProtocolHandler(ph2); 523 ASSERT_EQ(ph2, registry()->GetHandlerFor("test")); 524 ASSERT_TRUE(registry()->IsHandledProtocol("test")); 525} 526 527TEST_F(ProtocolHandlerRegistryTest, TestMostRecentHandlerIsDefault) { 528 ProtocolHandler ph1 = CreateProtocolHandler("test", "test1"); 529 ProtocolHandler ph2 = CreateProtocolHandler("test", "test2"); 530 registry()->OnAcceptRegisterProtocolHandler(ph1); 531 registry()->OnAcceptRegisterProtocolHandler(ph2); 532 ASSERT_FALSE(registry()->IsDefault(ph1)); 533 ASSERT_TRUE(registry()->IsDefault(ph2)); 534} 535 536TEST_F(ProtocolHandlerRegistryTest, TestOnAcceptRegisterProtocolHandler) { 537 ProtocolHandler ph1 = CreateProtocolHandler("test", "test1"); 538 ProtocolHandler ph2 = CreateProtocolHandler("test", "test2"); 539 registry()->OnAcceptRegisterProtocolHandler(ph1); 540 registry()->OnAcceptRegisterProtocolHandler(ph2); 541 542 registry()->OnAcceptRegisterProtocolHandler(ph1); 543 ASSERT_TRUE(registry()->IsDefault(ph1)); 544 ASSERT_FALSE(registry()->IsDefault(ph2)); 545 546 registry()->OnAcceptRegisterProtocolHandler(ph2); 547 ASSERT_FALSE(registry()->IsDefault(ph1)); 548 ASSERT_TRUE(registry()->IsDefault(ph2)); 549} 550 551TEST_F(ProtocolHandlerRegistryTest, TestDefaultSaveLoad) { 552 ProtocolHandler ph1 = CreateProtocolHandler("test", "test1"); 553 ProtocolHandler ph2 = CreateProtocolHandler("test", "test2"); 554 registry()->OnDenyRegisterProtocolHandler(ph1); 555 registry()->OnDenyRegisterProtocolHandler(ph2); 556 557 registry()->OnAcceptRegisterProtocolHandler(ph2); 558 registry()->Disable(); 559 560 RecreateRegistry(true); 561 562 ASSERT_FALSE(registry()->enabled()); 563 registry()->Enable(); 564 ASSERT_FALSE(registry()->IsDefault(ph1)); 565 ASSERT_TRUE(registry()->IsDefault(ph2)); 566 567 RecreateRegistry(true); 568 ASSERT_TRUE(registry()->enabled()); 569} 570 571TEST_F(ProtocolHandlerRegistryTest, TestRemoveHandler) { 572 ProtocolHandler ph1 = CreateProtocolHandler("test", "test1"); 573 registry()->OnAcceptRegisterProtocolHandler(ph1); 574 registry()->OnAcceptRegisterProtocolHandler(ph1); 575 576 registry()->RemoveHandler(ph1); 577 ASSERT_FALSE(registry()->IsRegistered(ph1)); 578 ASSERT_FALSE(registry()->IsHandledProtocol("test")); 579} 580 581TEST_F(ProtocolHandlerRegistryTest, TestIsRegistered) { 582 ProtocolHandler ph1 = CreateProtocolHandler("test", "test1"); 583 ProtocolHandler ph2 = CreateProtocolHandler("test", "test2"); 584 registry()->OnAcceptRegisterProtocolHandler(ph1); 585 registry()->OnAcceptRegisterProtocolHandler(ph2); 586 587 ASSERT_TRUE(registry()->IsRegistered(ph1)); 588} 589 590TEST_F(ProtocolHandlerRegistryTest, TestIsEquivalentRegistered) { 591 ProtocolHandler ph1 = CreateProtocolHandler("test", GURL("http://test/%s"), 592 "test1"); 593 ProtocolHandler ph2 = CreateProtocolHandler("test", GURL("http://test/%s"), 594 "test2"); 595 registry()->OnAcceptRegisterProtocolHandler(ph1); 596 597 ASSERT_TRUE(registry()->IsRegistered(ph1)); 598 ASSERT_TRUE(registry()->HasRegisteredEquivalent(ph2)); 599} 600 601TEST_F(ProtocolHandlerRegistryTest, TestSilentlyRegisterHandler) { 602 ProtocolHandler ph1 = CreateProtocolHandler("test", GURL("http://test/%s"), 603 "test1"); 604 ProtocolHandler ph2 = CreateProtocolHandler("test", GURL("http://test/%s"), 605 "test2"); 606 ProtocolHandler ph3 = CreateProtocolHandler("ignore", GURL("http://test/%s"), 607 "ignore1"); 608 ProtocolHandler ph4 = CreateProtocolHandler("ignore", GURL("http://test/%s"), 609 "ignore2"); 610 611 ASSERT_FALSE(registry()->SilentlyHandleRegisterHandlerRequest(ph1)); 612 ASSERT_FALSE(registry()->IsRegistered(ph1)); 613 614 registry()->OnAcceptRegisterProtocolHandler(ph1); 615 ASSERT_TRUE(registry()->IsRegistered(ph1)); 616 617 ASSERT_TRUE(registry()->SilentlyHandleRegisterHandlerRequest(ph2)); 618 ASSERT_FALSE(registry()->IsRegistered(ph1)); 619 ASSERT_TRUE(registry()->IsRegistered(ph2)); 620 621 ASSERT_FALSE(registry()->SilentlyHandleRegisterHandlerRequest(ph3)); 622 ASSERT_FALSE(registry()->IsRegistered(ph3)); 623 624 registry()->OnIgnoreRegisterProtocolHandler(ph3); 625 ASSERT_FALSE(registry()->IsRegistered(ph3)); 626 ASSERT_TRUE(registry()->IsIgnored(ph3)); 627 628 ASSERT_TRUE(registry()->SilentlyHandleRegisterHandlerRequest(ph4)); 629 ASSERT_FALSE(registry()->IsRegistered(ph4)); 630 ASSERT_TRUE(registry()->HasIgnoredEquivalent(ph4)); 631} 632 633TEST_F(ProtocolHandlerRegistryTest, MAYBE_TestRemoveHandlerRemovesDefault) { 634 ProtocolHandler ph1 = CreateProtocolHandler("test", "test1"); 635 ProtocolHandler ph2 = CreateProtocolHandler("test", "test2"); 636 ProtocolHandler ph3 = CreateProtocolHandler("test", "test3"); 637 638 registry()->OnAcceptRegisterProtocolHandler(ph1); 639 registry()->OnAcceptRegisterProtocolHandler(ph2); 640 registry()->OnAcceptRegisterProtocolHandler(ph3); 641 642 registry()->OnAcceptRegisterProtocolHandler(ph1); 643 registry()->RemoveHandler(ph1); 644 ASSERT_FALSE(registry()->IsDefault(ph1)); 645} 646 647TEST_F(ProtocolHandlerRegistryTest, TestGetHandlersFor) { 648 ProtocolHandler ph1 = CreateProtocolHandler("test", "test1"); 649 ProtocolHandler ph2 = CreateProtocolHandler("test", "test2"); 650 ProtocolHandler ph3 = CreateProtocolHandler("test", "test3"); 651 registry()->OnAcceptRegisterProtocolHandler(ph1); 652 registry()->OnAcceptRegisterProtocolHandler(ph2); 653 registry()->OnAcceptRegisterProtocolHandler(ph3); 654 655 ProtocolHandlerRegistry::ProtocolHandlerList handlers = 656 registry()->GetHandlersFor("test"); 657 ASSERT_EQ(static_cast<size_t>(3), handlers.size()); 658 659 ASSERT_EQ(ph3, handlers[0]); 660 ASSERT_EQ(ph2, handlers[1]); 661 ASSERT_EQ(ph1, handlers[2]); 662} 663 664TEST_F(ProtocolHandlerRegistryTest, TestGetRegisteredProtocols) { 665 std::vector<std::string> protocols; 666 registry()->GetRegisteredProtocols(&protocols); 667 ASSERT_EQ(static_cast<size_t>(0), protocols.size()); 668 669 registry()->GetHandlersFor("test"); 670 671 protocols.clear(); 672 registry()->GetRegisteredProtocols(&protocols); 673 ASSERT_EQ(static_cast<size_t>(0), protocols.size()); 674} 675 676TEST_F(ProtocolHandlerRegistryTest, TestIsHandledProtocol) { 677 registry()->GetHandlersFor("test"); 678 ASSERT_FALSE(registry()->IsHandledProtocol("test")); 679} 680 681TEST_F(ProtocolHandlerRegistryTest, TestNotifications) { 682 ProtocolHandler ph1 = CreateProtocolHandler("test", "test1"); 683 NotificationCounter counter(profile()); 684 685 registry()->OnAcceptRegisterProtocolHandler(ph1); 686 ASSERT_TRUE(counter.notified()); 687 counter.Clear(); 688 689 registry()->Disable(); 690 ASSERT_TRUE(counter.notified()); 691 counter.Clear(); 692 693 registry()->Enable(); 694 ASSERT_TRUE(counter.notified()); 695 counter.Clear(); 696 697 registry()->RemoveHandler(ph1); 698 ASSERT_TRUE(counter.notified()); 699 counter.Clear(); 700} 701 702TEST_F(ProtocolHandlerRegistryTest, TestReentrantNotifications) { 703 QueryProtocolHandlerOnChange queryer(profile(), registry()); 704 ProtocolHandler ph1 = CreateProtocolHandler("test", "test1"); 705 registry()->OnAcceptRegisterProtocolHandler(ph1); 706 ASSERT_TRUE(queryer.called_); 707} 708 709TEST_F(ProtocolHandlerRegistryTest, TestProtocolsWithNoDefaultAreHandled) { 710 ProtocolHandler ph1 = CreateProtocolHandler("test", "test1"); 711 registry()->OnAcceptRegisterProtocolHandler(ph1); 712 registry()->ClearDefault("test"); 713 std::vector<std::string> handled_protocols; 714 registry()->GetRegisteredProtocols(&handled_protocols); 715 ASSERT_EQ(static_cast<size_t>(1), handled_protocols.size()); 716 ASSERT_EQ("test", handled_protocols[0]); 717} 718 719TEST_F(ProtocolHandlerRegistryTest, TestDisablePreventsHandling) { 720 ProtocolHandler ph1 = CreateProtocolHandler("test", "test1"); 721 registry()->OnAcceptRegisterProtocolHandler(ph1); 722 ASSERT_TRUE(registry()->IsHandledProtocol("test")); 723 registry()->Disable(); 724 ASSERT_FALSE(registry()->IsHandledProtocol("test")); 725} 726 727// TODO(smckay): This is much more appropriately an integration 728// test. Make that so, then update the 729// ShellIntegretion{Delegate,Observer,Worker} test classes we use to fully 730// isolate this test from the FILE thread. 731TEST_F(ProtocolHandlerRegistryTest, TestOSRegistration) { 732 ProtocolHandler ph_do1 = CreateProtocolHandler("do", "test1"); 733 ProtocolHandler ph_do2 = CreateProtocolHandler("do", "test2"); 734 ProtocolHandler ph_dont = CreateProtocolHandler("dont", "test"); 735 736 ASSERT_FALSE(delegate()->IsFakeRegisteredWithOS("do")); 737 ASSERT_FALSE(delegate()->IsFakeRegisteredWithOS("dont")); 738 739 registry()->OnAcceptRegisterProtocolHandler(ph_do1); 740 registry()->OnDenyRegisterProtocolHandler(ph_dont); 741 base::MessageLoop::current()->Run(); // FILE thread needs to run. 742 ASSERT_TRUE(delegate()->IsFakeRegisteredWithOS("do")); 743 ASSERT_FALSE(delegate()->IsFakeRegisteredWithOS("dont")); 744 745 // This should not register with the OS, if it does the delegate 746 // will assert for us. We don't need to wait for the message loop 747 // as it should not go through to the shell worker. 748 registry()->OnAcceptRegisterProtocolHandler(ph_do2); 749} 750 751#if defined(OS_LINUX) 752// TODO(benwells): When Linux support is more reliable and 753// http://crbut.com/88255 is fixed this test will pass. 754#define MAYBE_TestOSRegistrationFailure DISABLED_TestOSRegistrationFailure 755#else 756#define MAYBE_TestOSRegistrationFailure TestOSRegistrationFailure 757#endif 758 759// TODO(smckay): This is much more appropriately an integration 760// test. Make that so, then update the 761// ShellIntegretion{Delegate,Observer,Worker} test classes we use to fully 762// isolate this test from the FILE thread. 763TEST_F(ProtocolHandlerRegistryTest, MAYBE_TestOSRegistrationFailure) { 764 ProtocolHandler ph_do = CreateProtocolHandler("do", "test1"); 765 ProtocolHandler ph_dont = CreateProtocolHandler("dont", "test"); 766 767 ASSERT_FALSE(registry()->IsHandledProtocol("do")); 768 ASSERT_FALSE(registry()->IsHandledProtocol("dont")); 769 770 registry()->OnAcceptRegisterProtocolHandler(ph_do); 771 base::MessageLoop::current()->Run(); // FILE thread needs to run. 772 delegate()->set_force_os_failure(true); 773 registry()->OnAcceptRegisterProtocolHandler(ph_dont); 774 base::MessageLoop::current()->Run(); // FILE thread needs to run. 775 ASSERT_TRUE(registry()->IsHandledProtocol("do")); 776 ASSERT_EQ(static_cast<size_t>(1), registry()->GetHandlersFor("do").size()); 777 ASSERT_FALSE(registry()->IsHandledProtocol("dont")); 778 ASSERT_EQ(static_cast<size_t>(1), registry()->GetHandlersFor("dont").size()); 779} 780 781TEST_F(ProtocolHandlerRegistryTest, TestMaybeCreateTaskWorksFromIOThread) { 782 ProtocolHandler ph1 = CreateProtocolHandler("mailto", "test1"); 783 registry()->OnAcceptRegisterProtocolHandler(ph1); 784 GURL url("mailto:someone@something.com"); 785 786 scoped_ptr<net::URLRequestJobFactory> interceptor( 787 registry()->CreateJobInterceptorFactory()); 788 AssertIntercepted(url, interceptor.get()); 789} 790 791TEST_F(ProtocolHandlerRegistryTest, 792 MAYBE_TestIsHandledProtocolWorksOnIOThread) { 793 std::string scheme("mailto"); 794 ProtocolHandler ph1 = CreateProtocolHandler(scheme, "test1"); 795 registry()->OnAcceptRegisterProtocolHandler(ph1); 796 797 scoped_ptr<ProtocolHandlerRegistry::JobInterceptorFactory> interceptor( 798 registry()->CreateJobInterceptorFactory()); 799 AssertWillHandle(scheme, true, interceptor.get()); 800} 801 802TEST_F(ProtocolHandlerRegistryTest, TestRemovingDefaultFallsBackToOldDefault) { 803 ProtocolHandler ph1 = CreateProtocolHandler("mailto", "test1"); 804 ProtocolHandler ph2 = CreateProtocolHandler("mailto", "test2"); 805 ProtocolHandler ph3 = CreateProtocolHandler("mailto", "test3"); 806 registry()->OnAcceptRegisterProtocolHandler(ph1); 807 registry()->OnAcceptRegisterProtocolHandler(ph2); 808 registry()->OnAcceptRegisterProtocolHandler(ph3); 809 810 ASSERT_TRUE(registry()->IsDefault(ph3)); 811 registry()->RemoveHandler(ph3); 812 ASSERT_TRUE(registry()->IsDefault(ph2)); 813 registry()->OnAcceptRegisterProtocolHandler(ph3); 814 ASSERT_TRUE(registry()->IsDefault(ph3)); 815 registry()->RemoveHandler(ph2); 816 ASSERT_TRUE(registry()->IsDefault(ph3)); 817 registry()->RemoveHandler(ph3); 818 ASSERT_TRUE(registry()->IsDefault(ph1)); 819} 820 821TEST_F(ProtocolHandlerRegistryTest, TestRemovingDefaultDoesntChangeHandlers) { 822 ProtocolHandler ph1 = CreateProtocolHandler("mailto", "test1"); 823 ProtocolHandler ph2 = CreateProtocolHandler("mailto", "test2"); 824 ProtocolHandler ph3 = CreateProtocolHandler("mailto", "test3"); 825 registry()->OnAcceptRegisterProtocolHandler(ph1); 826 registry()->OnAcceptRegisterProtocolHandler(ph2); 827 registry()->OnAcceptRegisterProtocolHandler(ph3); 828 registry()->RemoveHandler(ph3); 829 830 ProtocolHandlerRegistry::ProtocolHandlerList handlers = 831 registry()->GetHandlersFor("mailto"); 832 ASSERT_EQ(static_cast<size_t>(2), handlers.size()); 833 834 ASSERT_EQ(ph2, handlers[0]); 835 ASSERT_EQ(ph1, handlers[1]); 836} 837 838TEST_F(ProtocolHandlerRegistryTest, MAYBE_TestClearDefaultGetsPropagatedToIO) { 839 std::string scheme("mailto"); 840 ProtocolHandler ph1 = CreateProtocolHandler(scheme, "test1"); 841 registry()->OnAcceptRegisterProtocolHandler(ph1); 842 registry()->ClearDefault(scheme); 843 844 scoped_ptr<ProtocolHandlerRegistry::JobInterceptorFactory> interceptor( 845 registry()->CreateJobInterceptorFactory()); 846 AssertWillHandle(scheme, false, interceptor.get()); 847} 848 849TEST_F(ProtocolHandlerRegistryTest, TestLoadEnabledGetsPropogatedToIO) { 850 std::string mailto("mailto"); 851 ProtocolHandler ph1 = CreateProtocolHandler(mailto, "MailtoHandler"); 852 registry()->OnAcceptRegisterProtocolHandler(ph1); 853 854 scoped_ptr<ProtocolHandlerRegistry::JobInterceptorFactory> interceptor( 855 registry()->CreateJobInterceptorFactory()); 856 AssertWillHandle(mailto, true, interceptor.get()); 857 registry()->Disable(); 858 AssertWillHandle(mailto, false, interceptor.get()); 859} 860 861TEST_F(ProtocolHandlerRegistryTest, TestReplaceHandler) { 862 ProtocolHandler ph1 = CreateProtocolHandler("mailto", 863 GURL("http://test.com/%s"), "test1"); 864 ProtocolHandler ph2 = CreateProtocolHandler("mailto", 865 GURL("http://test.com/updated-url/%s"), "test2"); 866 registry()->OnAcceptRegisterProtocolHandler(ph1); 867 ASSERT_TRUE(registry()->AttemptReplace(ph2)); 868 const ProtocolHandler& handler(registry()->GetHandlerFor("mailto")); 869 ASSERT_EQ(handler.url(), ph2.url()); 870} 871 872TEST_F(ProtocolHandlerRegistryTest, TestReplaceNonDefaultHandler) { 873 ProtocolHandler ph1 = CreateProtocolHandler("mailto", 874 GURL("http://test.com/%s"), "test1"); 875 ProtocolHandler ph2 = CreateProtocolHandler("mailto", 876 GURL("http://test.com/updated-url/%s"), "test2"); 877 ProtocolHandler ph3 = CreateProtocolHandler("mailto", 878 GURL("http://else.com/%s"), "test3"); 879 registry()->OnAcceptRegisterProtocolHandler(ph1); 880 registry()->OnAcceptRegisterProtocolHandler(ph3); 881 ASSERT_TRUE(registry()->AttemptReplace(ph2)); 882 const ProtocolHandler& handler(registry()->GetHandlerFor("mailto")); 883 ASSERT_EQ(handler.url(), ph3.url()); 884} 885 886TEST_F(ProtocolHandlerRegistryTest, TestReplaceRemovesStaleHandlers) { 887 ProtocolHandler ph1 = CreateProtocolHandler("mailto", 888 GURL("http://test.com/%s"), "test1"); 889 ProtocolHandler ph2 = CreateProtocolHandler("mailto", 890 GURL("http://test.com/updated-url/%s"), "test2"); 891 ProtocolHandler ph3 = CreateProtocolHandler("mailto", 892 GURL("http://test.com/third/%s"), "test"); 893 registry()->OnAcceptRegisterProtocolHandler(ph1); 894 registry()->OnAcceptRegisterProtocolHandler(ph2); 895 896 // This should replace the previous two handlers. 897 ASSERT_TRUE(registry()->AttemptReplace(ph3)); 898 const ProtocolHandler& handler(registry()->GetHandlerFor("mailto")); 899 ASSERT_EQ(handler.url(), ph3.url()); 900 registry()->RemoveHandler(ph3); 901 ASSERT_TRUE(registry()->GetHandlerFor("mailto").IsEmpty()); 902} 903 904TEST_F(ProtocolHandlerRegistryTest, TestIsSameOrigin) { 905 ProtocolHandler ph1 = CreateProtocolHandler("mailto", 906 GURL("http://test.com/%s"), "test1"); 907 ProtocolHandler ph2 = CreateProtocolHandler("mailto", 908 GURL("http://test.com/updated-url/%s"), "test2"); 909 ProtocolHandler ph3 = CreateProtocolHandler("mailto", 910 GURL("http://other.com/%s"), "test"); 911 ASSERT_EQ(ph1.url().GetOrigin() == ph2.url().GetOrigin(), 912 ph1.IsSameOrigin(ph2)); 913 ASSERT_EQ(ph1.url().GetOrigin() == ph2.url().GetOrigin(), 914 ph2.IsSameOrigin(ph1)); 915 ASSERT_EQ(ph2.url().GetOrigin() == ph3.url().GetOrigin(), 916 ph2.IsSameOrigin(ph3)); 917 ASSERT_EQ(ph3.url().GetOrigin() == ph2.url().GetOrigin(), 918 ph3.IsSameOrigin(ph2)); 919} 920 921TEST_F(ProtocolHandlerRegistryTest, MAYBE_TestInstallDefaultHandler) { 922 RecreateRegistry(false); 923 registry()->AddPredefinedHandler(CreateProtocolHandler( 924 "test", GURL("http://test.com/%s"), "Test")); 925 registry()->InitProtocolSettings(); 926 std::vector<std::string> protocols; 927 registry()->GetRegisteredProtocols(&protocols); 928 ASSERT_EQ(static_cast<size_t>(1), protocols.size()); 929} 930