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.
5 #include "chrome/browser/custom_handlers/protocol_handler_registry.h"
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"
29 using content::BrowserThread
;
33 void AssertInterceptedIO(
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
);
45 void AssertIntercepted(
47 net::URLRequestJobFactory
* interceptor
) {
48 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
49 BrowserThread::PostTask(BrowserThread::IO
,
51 base::Bind(AssertInterceptedIO
,
53 base::Unretained(interceptor
)));
54 base::MessageLoop::current()->RunUntilIdle();
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.
62 class 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
{
70 virtual bool IsHandledProtocol(const std::string
& scheme
) const OVERRIDE
{
73 virtual bool IsHandledURL(const GURL
& url
) const OVERRIDE
{
76 virtual bool IsSafeRedirectTarget(const GURL
& location
) const OVERRIDE
{
81 void AssertWillHandleIO(
82 const std::string
& scheme
,
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
>());
92 void AssertWillHandle(
93 const std::string
& scheme
,
95 ProtocolHandlerRegistry::JobInterceptorFactory
* interceptor
) {
96 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
97 BrowserThread::PostTask(BrowserThread::IO
,
99 base::Bind(AssertWillHandleIO
,
102 base::Unretained(interceptor
)));
103 base::MessageLoop::current()->RunUntilIdle();
106 class FakeDelegate
: public ProtocolHandlerRegistry::Delegate
{
108 FakeDelegate() : force_os_failure_(false) {}
109 virtual ~FakeDelegate() { }
110 virtual void RegisterExternalHandler(const std::string
& protocol
) OVERRIDE
{
112 registered_protocols_
.find(protocol
) == registered_protocols_
.end());
113 registered_protocols_
.insert(protocol
);
116 virtual void DeregisterExternalHandler(const std::string
& protocol
) OVERRIDE
{
117 registered_protocols_
.erase(protocol
);
120 virtual ShellIntegration::DefaultProtocolClientWorker
* CreateShellWorker(
121 ShellIntegration::DefaultWebClientObserver
* observer
,
122 const std::string
& protocol
) OVERRIDE
;
124 virtual ProtocolHandlerRegistry::DefaultClientObserver
* CreateShellObserver(
125 ProtocolHandlerRegistry
* registry
) OVERRIDE
;
127 virtual void RegisterWithOSAsDefaultClient(
128 const std::string
& protocol
,
129 ProtocolHandlerRegistry
* reg
) OVERRIDE
{
130 ProtocolHandlerRegistry::Delegate::RegisterWithOSAsDefaultClient(protocol
,
132 ASSERT_FALSE(IsFakeRegisteredWithOS(protocol
));
135 virtual bool IsExternalHandlerRegistered(
136 const std::string
& protocol
) OVERRIDE
{
137 return registered_protocols_
.find(protocol
) != registered_protocols_
.end();
140 bool IsFakeRegisteredWithOS(const std::string
& protocol
) {
141 return os_registered_protocols_
.find(protocol
) !=
142 os_registered_protocols_
.end();
145 void FakeRegisterWithOS(const std::string
& protocol
) {
146 os_registered_protocols_
.insert(protocol
);
150 registered_protocols_
.clear();
151 os_registered_protocols_
.clear();
152 force_os_failure_
= false;
155 void set_force_os_failure(bool force
) { force_os_failure_
= force
; }
157 bool force_os_failure() { return force_os_failure_
; }
160 std::set
<std::string
> registered_protocols_
;
161 std::set
<std::string
> os_registered_protocols_
;
162 bool force_os_failure_
;
165 class FakeClientObserver
166 : public ProtocolHandlerRegistry::DefaultClientObserver
{
168 FakeClientObserver(ProtocolHandlerRegistry
* registry
,
169 FakeDelegate
* registry_delegate
)
170 : ProtocolHandlerRegistry::DefaultClientObserver(registry
),
171 delegate_(registry_delegate
) {}
173 virtual void SetDefaultWebClientUIState(
174 ShellIntegration::DefaultWebClientUIState state
) OVERRIDE
{
175 ProtocolHandlerRegistry::DefaultClientObserver::SetDefaultWebClientUIState(
177 if (state
== ShellIntegration::STATE_IS_DEFAULT
) {
178 delegate_
->FakeRegisterWithOS(worker_
->protocol());
180 if (state
!= ShellIntegration::STATE_PROCESSING
) {
181 base::MessageLoop::current()->Quit();
186 FakeDelegate
* delegate_
;
189 class FakeProtocolClientWorker
190 : public ShellIntegration::DefaultProtocolClientWorker
{
192 FakeProtocolClientWorker(ShellIntegration::DefaultWebClientObserver
* observer
,
193 const std::string
& protocol
,
195 : ShellIntegration::DefaultProtocolClientWorker(observer
, protocol
),
196 force_failure_(force_failure
) {}
199 virtual ~FakeProtocolClientWorker() {}
201 virtual ShellIntegration::DefaultWebClientState
CheckIsDefault() OVERRIDE
{
202 if (force_failure_
) {
203 return ShellIntegration::NOT_DEFAULT
;
205 return ShellIntegration::IS_DEFAULT
;
209 virtual bool SetAsDefault(bool interactive_permitted
) OVERRIDE
{
217 ProtocolHandlerRegistry::DefaultClientObserver
*
218 FakeDelegate::CreateShellObserver(ProtocolHandlerRegistry
* registry
) {
219 return new FakeClientObserver(registry
, this);
222 ShellIntegration::DefaultProtocolClientWorker
* FakeDelegate::CreateShellWorker(
223 ShellIntegration::DefaultWebClientObserver
* observer
,
224 const std::string
& protocol
) {
225 return new FakeProtocolClientWorker(observer
, protocol
, force_os_failure_
);
228 class NotificationCounter
: public content::NotificationObserver
{
230 explicit NotificationCounter(Profile
* profile
)
232 notification_registrar_() {
233 notification_registrar_
.Add(this,
234 chrome::NOTIFICATION_PROTOCOL_HANDLER_REGISTRY_CHANGED
,
235 content::Source
<Profile
>(profile
));
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
{
248 content::NotificationRegistrar notification_registrar_
;
251 class QueryProtocolHandlerOnChange
252 : public content::NotificationObserver
{
254 QueryProtocolHandlerOnChange(Profile
* profile
,
255 ProtocolHandlerRegistry
* registry
)
256 : local_registry_(registry
),
258 notification_registrar_() {
259 notification_registrar_
.Add(this,
260 chrome::NOTIFICATION_PROTOCOL_HANDLER_REGISTRY_CHANGED
,
261 content::Source
<Profile
>(profile
));
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
);
272 ProtocolHandlerRegistry
* local_registry_
;
274 content::NotificationRegistrar notification_registrar_
;
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!
283 class TestMessageLoop
: public base::MessageLoop
{
286 virtual ~TestMessageLoop() {}
287 virtual bool IsType(base::MessageLoop::Type type
) const OVERRIDE
{
289 #if defined(TOOLKIT_GTK)
290 case base::MessageLoop::TYPE_GPU
:
292 case base::MessageLoop::TYPE_UI
:
293 return BrowserThread::CurrentlyOn(BrowserThread::UI
);
294 case base::MessageLoop::TYPE_IO
:
295 return BrowserThread::CurrentlyOn(BrowserThread::IO
);
296 #if defined(OS_ANDROID)
297 case base::MessageLoop::TYPE_JAVA
: // fall-through
298 #endif // defined(OS_ANDROID)
299 case base::MessageLoop::TYPE_CUSTOM
:
300 case base::MessageLoop::TYPE_DEFAULT
:
301 return !BrowserThread::CurrentlyOn(BrowserThread::UI
) &&
302 !BrowserThread::CurrentlyOn(BrowserThread::IO
);
310 class ProtocolHandlerRegistryTest
: public testing::Test
{
312 ProtocolHandlerRegistryTest()
313 : ui_thread_(BrowserThread::UI
, &loop_
),
314 file_thread_(BrowserThread::FILE, &loop_
),
315 io_thread_(BrowserThread::IO
, &loop_
),
316 test_protocol_handler_(CreateProtocolHandler("test", "test")) {}
318 FakeDelegate
* delegate() const { return delegate_
; }
319 ProtocolHandlerRegistry
* registry() { return registry_
.get(); }
320 TestingProfile
* profile() const { return profile_
.get(); }
321 const ProtocolHandler
& test_protocol_handler() const {
322 return test_protocol_handler_
;
325 ProtocolHandler
CreateProtocolHandler(const std::string
& protocol
,
327 const std::string
& title
) {
328 return ProtocolHandler::CreateProtocolHandler(protocol
, url
,
329 base::UTF8ToUTF16(title
));
332 ProtocolHandler
CreateProtocolHandler(const std::string
& protocol
,
333 const std::string
& name
) {
334 return CreateProtocolHandler(protocol
, GURL("http://" + name
+ "/%s"),
338 void RecreateRegistry(bool initialize
) {
340 SetUpRegistry(initialize
);
343 // Returns a new registry, initializing it if |initialize| is true.
344 // Caller assumes ownership for the object
345 void SetUpRegistry(bool initialize
) {
346 delegate_
= new FakeDelegate();
347 registry_
.reset(new ProtocolHandlerRegistry(profile(), delegate()));
348 if (initialize
) registry_
->InitProtocolSettings();
351 void TeadDownRegistry() {
352 registry_
->Shutdown();
354 // Registry owns the delegate_ it handles deletion of that object.
357 virtual void SetUp() {
358 profile_
.reset(new TestingProfile());
359 CHECK(profile_
->GetPrefs());
361 test_protocol_handler_
=
362 CreateProtocolHandler("test", GURL("http://test.com/%s"), "Test");
365 virtual void TearDown() {
369 TestMessageLoop loop_
;
372 content::TestBrowserThread ui_thread_
;
373 content::TestBrowserThread file_thread_
;
374 content::TestBrowserThread io_thread_
;
376 scoped_ptr
<TestingProfile
> profile_
;
377 FakeDelegate
* delegate_
; // Registry assumes ownership of delegate_.
378 scoped_ptr
<ProtocolHandlerRegistry
> registry_
;
379 ProtocolHandler test_protocol_handler_
;
382 // ProtocolHandlerRegistryTest tests are flaky on Linux & ChromeOS.
383 // http://crbug.com/133023
384 #if defined(OS_LINUX) || defined(OS_CHROMEOS)
385 #define MAYBE_AcceptProtocolHandlerHandlesProtocol \
386 DISABLED_AcceptProtocolHandlerHandlesProtocol
387 #define MAYBE_DeniedProtocolIsntHandledUntilAccepted \
388 DISABLED_DeniedProtocolIsntHandledUntilAccepted
389 #define MAYBE_TestStartsAsDefault DISABLED_TestStartsAsDefault
390 #define MAYBE_TestRemoveHandlerRemovesDefault \
391 DISABLED_TestRemoveHandlerRemovesDefault
392 #define MAYBE_TestClearDefaultGetsPropagatedToIO \
393 DISABLED_TestClearDefaultGetsPropagatedToIO
394 #define MAYBE_TestIsHandledProtocolWorksOnIOThread \
395 DISABLED_TestIsHandledProtocolWorksOnIOThread
396 #define MAYBE_TestInstallDefaultHandler \
397 DISABLED_TestInstallDefaultHandler
399 #define MAYBE_AcceptProtocolHandlerHandlesProtocol \
400 AcceptProtocolHandlerHandlesProtocol
401 #define MAYBE_DeniedProtocolIsntHandledUntilAccepted \
402 DeniedProtocolIsntHandledUntilAccepted
403 #define MAYBE_TestStartsAsDefault TestStartsAsDefault
404 #define MAYBE_TestRemoveHandlerRemovesDefault TestRemoveHandlerRemovesDefault
405 #define MAYBE_TestClearDefaultGetsPropagatedToIO \
406 TestClearDefaultGetsPropagatedToIO
407 #define MAYBE_TestIsHandledProtocolWorksOnIOThread \
408 TestIsHandledProtocolWorksOnIOThread
409 #define MAYBE_TestInstallDefaultHandler TestInstallDefaultHandler
410 #endif // defined(OS_CHROMEOS)
412 TEST_F(ProtocolHandlerRegistryTest
,
413 MAYBE_AcceptProtocolHandlerHandlesProtocol
) {
414 ASSERT_FALSE(registry()->IsHandledProtocol("test"));
415 registry()->OnAcceptRegisterProtocolHandler(test_protocol_handler());
416 ASSERT_TRUE(registry()->IsHandledProtocol("test"));
419 TEST_F(ProtocolHandlerRegistryTest
,
420 MAYBE_DeniedProtocolIsntHandledUntilAccepted
) {
421 registry()->OnDenyRegisterProtocolHandler(test_protocol_handler());
422 ASSERT_FALSE(registry()->IsHandledProtocol("test"));
423 registry()->OnAcceptRegisterProtocolHandler(test_protocol_handler());
424 ASSERT_TRUE(registry()->IsHandledProtocol("test"));
427 TEST_F(ProtocolHandlerRegistryTest
, ClearDefaultMakesProtocolNotHandled
) {
428 registry()->OnAcceptRegisterProtocolHandler(test_protocol_handler());
429 registry()->ClearDefault("test");
430 ASSERT_FALSE(registry()->IsHandledProtocol("test"));
431 ASSERT_TRUE(registry()->GetHandlerFor("test").IsEmpty());
434 TEST_F(ProtocolHandlerRegistryTest
, DisableDeregistersProtocolHandlers
) {
435 ASSERT_FALSE(delegate()->IsExternalHandlerRegistered("test"));
436 registry()->OnAcceptRegisterProtocolHandler(test_protocol_handler());
437 ASSERT_TRUE(delegate()->IsExternalHandlerRegistered("test"));
439 registry()->Disable();
440 ASSERT_FALSE(delegate()->IsExternalHandlerRegistered("test"));
441 registry()->Enable();
442 ASSERT_TRUE(delegate()->IsExternalHandlerRegistered("test"));
445 TEST_F(ProtocolHandlerRegistryTest
, IgnoreProtocolHandler
) {
446 registry()->OnIgnoreRegisterProtocolHandler(test_protocol_handler());
447 ASSERT_TRUE(registry()->IsIgnored(test_protocol_handler()));
449 registry()->RemoveIgnoredHandler(test_protocol_handler());
450 ASSERT_FALSE(registry()->IsIgnored(test_protocol_handler()));
453 TEST_F(ProtocolHandlerRegistryTest
, IgnoreEquivalentProtocolHandler
) {
454 ProtocolHandler ph1
= CreateProtocolHandler("test", GURL("http://test/%s"),
456 ProtocolHandler ph2
= CreateProtocolHandler("test", GURL("http://test/%s"),
459 registry()->OnIgnoreRegisterProtocolHandler(ph1
);
460 ASSERT_TRUE(registry()->IsIgnored(ph1
));
461 ASSERT_TRUE(registry()->HasIgnoredEquivalent(ph2
));
463 registry()->RemoveIgnoredHandler(ph1
);
464 ASSERT_FALSE(registry()->IsIgnored(ph1
));
465 ASSERT_FALSE(registry()->HasIgnoredEquivalent(ph2
));
468 TEST_F(ProtocolHandlerRegistryTest
, SaveAndLoad
) {
469 ProtocolHandler
stuff_protocol_handler(
470 CreateProtocolHandler("stuff", "stuff"));
471 registry()->OnAcceptRegisterProtocolHandler(test_protocol_handler());
472 registry()->OnIgnoreRegisterProtocolHandler(stuff_protocol_handler
);
474 ASSERT_TRUE(registry()->IsHandledProtocol("test"));
475 ASSERT_TRUE(registry()->IsIgnored(stuff_protocol_handler
));
477 RecreateRegistry(true);
478 ASSERT_TRUE(registry()->IsHandledProtocol("test"));
479 ASSERT_TRUE(registry()->IsIgnored(stuff_protocol_handler
));
482 TEST_F(ProtocolHandlerRegistryTest
, TestEnabledDisabled
) {
483 registry()->Disable();
484 ASSERT_FALSE(registry()->enabled());
485 registry()->Enable();
486 ASSERT_TRUE(registry()->enabled());
489 TEST_F(ProtocolHandlerRegistryTest
,
490 DisallowRegisteringExternallyHandledProtocols
) {
491 delegate()->RegisterExternalHandler("test");
492 ASSERT_FALSE(registry()->CanSchemeBeOverridden("test"));
495 TEST_F(ProtocolHandlerRegistryTest
, RemovingHandlerMeansItCanBeAddedAgain
) {
496 registry()->OnAcceptRegisterProtocolHandler(test_protocol_handler());
497 ASSERT_TRUE(registry()->CanSchemeBeOverridden("test"));
498 registry()->RemoveHandler(test_protocol_handler());
499 ASSERT_TRUE(registry()->CanSchemeBeOverridden("test"));
502 TEST_F(ProtocolHandlerRegistryTest
, MAYBE_TestStartsAsDefault
) {
503 registry()->OnAcceptRegisterProtocolHandler(test_protocol_handler());
504 ASSERT_TRUE(registry()->IsDefault(test_protocol_handler()));
507 TEST_F(ProtocolHandlerRegistryTest
, TestClearDefault
) {
508 ProtocolHandler ph1
= CreateProtocolHandler("test", "test1");
509 ProtocolHandler ph2
= CreateProtocolHandler("test", "test2");
510 registry()->OnAcceptRegisterProtocolHandler(ph1
);
511 registry()->OnAcceptRegisterProtocolHandler(ph2
);
513 registry()->OnAcceptRegisterProtocolHandler(ph1
);
514 registry()->ClearDefault("test");
515 ASSERT_FALSE(registry()->IsDefault(ph1
));
516 ASSERT_FALSE(registry()->IsDefault(ph2
));
519 TEST_F(ProtocolHandlerRegistryTest
, TestGetHandlerFor
) {
520 ProtocolHandler ph1
= CreateProtocolHandler("test", "test1");
521 ProtocolHandler ph2
= CreateProtocolHandler("test", "test2");
522 registry()->OnAcceptRegisterProtocolHandler(ph1
);
523 registry()->OnAcceptRegisterProtocolHandler(ph2
);
525 registry()->OnAcceptRegisterProtocolHandler(ph2
);
526 ASSERT_EQ(ph2
, registry()->GetHandlerFor("test"));
527 ASSERT_TRUE(registry()->IsHandledProtocol("test"));
530 TEST_F(ProtocolHandlerRegistryTest
, TestMostRecentHandlerIsDefault
) {
531 ProtocolHandler ph1
= CreateProtocolHandler("test", "test1");
532 ProtocolHandler ph2
= CreateProtocolHandler("test", "test2");
533 registry()->OnAcceptRegisterProtocolHandler(ph1
);
534 registry()->OnAcceptRegisterProtocolHandler(ph2
);
535 ASSERT_FALSE(registry()->IsDefault(ph1
));
536 ASSERT_TRUE(registry()->IsDefault(ph2
));
539 TEST_F(ProtocolHandlerRegistryTest
, TestOnAcceptRegisterProtocolHandler
) {
540 ProtocolHandler ph1
= CreateProtocolHandler("test", "test1");
541 ProtocolHandler ph2
= CreateProtocolHandler("test", "test2");
542 registry()->OnAcceptRegisterProtocolHandler(ph1
);
543 registry()->OnAcceptRegisterProtocolHandler(ph2
);
545 registry()->OnAcceptRegisterProtocolHandler(ph1
);
546 ASSERT_TRUE(registry()->IsDefault(ph1
));
547 ASSERT_FALSE(registry()->IsDefault(ph2
));
549 registry()->OnAcceptRegisterProtocolHandler(ph2
);
550 ASSERT_FALSE(registry()->IsDefault(ph1
));
551 ASSERT_TRUE(registry()->IsDefault(ph2
));
554 TEST_F(ProtocolHandlerRegistryTest
, TestDefaultSaveLoad
) {
555 ProtocolHandler ph1
= CreateProtocolHandler("test", "test1");
556 ProtocolHandler ph2
= CreateProtocolHandler("test", "test2");
557 registry()->OnDenyRegisterProtocolHandler(ph1
);
558 registry()->OnDenyRegisterProtocolHandler(ph2
);
560 registry()->OnAcceptRegisterProtocolHandler(ph2
);
561 registry()->Disable();
563 RecreateRegistry(true);
565 ASSERT_FALSE(registry()->enabled());
566 registry()->Enable();
567 ASSERT_FALSE(registry()->IsDefault(ph1
));
568 ASSERT_TRUE(registry()->IsDefault(ph2
));
570 RecreateRegistry(true);
571 ASSERT_TRUE(registry()->enabled());
574 TEST_F(ProtocolHandlerRegistryTest
, TestRemoveHandler
) {
575 ProtocolHandler ph1
= CreateProtocolHandler("test", "test1");
576 registry()->OnAcceptRegisterProtocolHandler(ph1
);
577 registry()->OnAcceptRegisterProtocolHandler(ph1
);
579 registry()->RemoveHandler(ph1
);
580 ASSERT_FALSE(registry()->IsRegistered(ph1
));
581 ASSERT_FALSE(registry()->IsHandledProtocol("test"));
584 TEST_F(ProtocolHandlerRegistryTest
, TestIsRegistered
) {
585 ProtocolHandler ph1
= CreateProtocolHandler("test", "test1");
586 ProtocolHandler ph2
= CreateProtocolHandler("test", "test2");
587 registry()->OnAcceptRegisterProtocolHandler(ph1
);
588 registry()->OnAcceptRegisterProtocolHandler(ph2
);
590 ASSERT_TRUE(registry()->IsRegistered(ph1
));
593 TEST_F(ProtocolHandlerRegistryTest
, TestIsEquivalentRegistered
) {
594 ProtocolHandler ph1
= CreateProtocolHandler("test", GURL("http://test/%s"),
596 ProtocolHandler ph2
= CreateProtocolHandler("test", GURL("http://test/%s"),
598 registry()->OnAcceptRegisterProtocolHandler(ph1
);
600 ASSERT_TRUE(registry()->IsRegistered(ph1
));
601 ASSERT_TRUE(registry()->HasRegisteredEquivalent(ph2
));
604 TEST_F(ProtocolHandlerRegistryTest
, TestSilentlyRegisterHandler
) {
605 ProtocolHandler ph1
= CreateProtocolHandler("test", GURL("http://test/%s"),
607 ProtocolHandler ph2
= CreateProtocolHandler("test", GURL("http://test/%s"),
609 ProtocolHandler ph3
= CreateProtocolHandler("ignore", GURL("http://test/%s"),
611 ProtocolHandler ph4
= CreateProtocolHandler("ignore", GURL("http://test/%s"),
614 ASSERT_FALSE(registry()->SilentlyHandleRegisterHandlerRequest(ph1
));
615 ASSERT_FALSE(registry()->IsRegistered(ph1
));
617 registry()->OnAcceptRegisterProtocolHandler(ph1
);
618 ASSERT_TRUE(registry()->IsRegistered(ph1
));
620 ASSERT_TRUE(registry()->SilentlyHandleRegisterHandlerRequest(ph2
));
621 ASSERT_FALSE(registry()->IsRegistered(ph1
));
622 ASSERT_TRUE(registry()->IsRegistered(ph2
));
624 ASSERT_FALSE(registry()->SilentlyHandleRegisterHandlerRequest(ph3
));
625 ASSERT_FALSE(registry()->IsRegistered(ph3
));
627 registry()->OnIgnoreRegisterProtocolHandler(ph3
);
628 ASSERT_FALSE(registry()->IsRegistered(ph3
));
629 ASSERT_TRUE(registry()->IsIgnored(ph3
));
631 ASSERT_TRUE(registry()->SilentlyHandleRegisterHandlerRequest(ph4
));
632 ASSERT_FALSE(registry()->IsRegistered(ph4
));
633 ASSERT_TRUE(registry()->HasIgnoredEquivalent(ph4
));
636 TEST_F(ProtocolHandlerRegistryTest
, MAYBE_TestRemoveHandlerRemovesDefault
) {
637 ProtocolHandler ph1
= CreateProtocolHandler("test", "test1");
638 ProtocolHandler ph2
= CreateProtocolHandler("test", "test2");
639 ProtocolHandler ph3
= CreateProtocolHandler("test", "test3");
641 registry()->OnAcceptRegisterProtocolHandler(ph1
);
642 registry()->OnAcceptRegisterProtocolHandler(ph2
);
643 registry()->OnAcceptRegisterProtocolHandler(ph3
);
645 registry()->OnAcceptRegisterProtocolHandler(ph1
);
646 registry()->RemoveHandler(ph1
);
647 ASSERT_FALSE(registry()->IsDefault(ph1
));
650 TEST_F(ProtocolHandlerRegistryTest
, TestGetHandlersFor
) {
651 ProtocolHandler ph1
= CreateProtocolHandler("test", "test1");
652 ProtocolHandler ph2
= CreateProtocolHandler("test", "test2");
653 ProtocolHandler ph3
= CreateProtocolHandler("test", "test3");
654 registry()->OnAcceptRegisterProtocolHandler(ph1
);
655 registry()->OnAcceptRegisterProtocolHandler(ph2
);
656 registry()->OnAcceptRegisterProtocolHandler(ph3
);
658 ProtocolHandlerRegistry::ProtocolHandlerList handlers
=
659 registry()->GetHandlersFor("test");
660 ASSERT_EQ(static_cast<size_t>(3), handlers
.size());
662 ASSERT_EQ(ph3
, handlers
[0]);
663 ASSERT_EQ(ph2
, handlers
[1]);
664 ASSERT_EQ(ph1
, handlers
[2]);
667 TEST_F(ProtocolHandlerRegistryTest
, TestGetRegisteredProtocols
) {
668 std::vector
<std::string
> protocols
;
669 registry()->GetRegisteredProtocols(&protocols
);
670 ASSERT_EQ(static_cast<size_t>(0), protocols
.size());
672 registry()->GetHandlersFor("test");
675 registry()->GetRegisteredProtocols(&protocols
);
676 ASSERT_EQ(static_cast<size_t>(0), protocols
.size());
679 TEST_F(ProtocolHandlerRegistryTest
, TestIsHandledProtocol
) {
680 registry()->GetHandlersFor("test");
681 ASSERT_FALSE(registry()->IsHandledProtocol("test"));
684 TEST_F(ProtocolHandlerRegistryTest
, TestNotifications
) {
685 ProtocolHandler ph1
= CreateProtocolHandler("test", "test1");
686 NotificationCounter
counter(profile());
688 registry()->OnAcceptRegisterProtocolHandler(ph1
);
689 ASSERT_TRUE(counter
.notified());
692 registry()->Disable();
693 ASSERT_TRUE(counter
.notified());
696 registry()->Enable();
697 ASSERT_TRUE(counter
.notified());
700 registry()->RemoveHandler(ph1
);
701 ASSERT_TRUE(counter
.notified());
705 TEST_F(ProtocolHandlerRegistryTest
, TestReentrantNotifications
) {
706 QueryProtocolHandlerOnChange
queryer(profile(), registry());
707 ProtocolHandler ph1
= CreateProtocolHandler("test", "test1");
708 registry()->OnAcceptRegisterProtocolHandler(ph1
);
709 ASSERT_TRUE(queryer
.called_
);
712 TEST_F(ProtocolHandlerRegistryTest
, TestProtocolsWithNoDefaultAreHandled
) {
713 ProtocolHandler ph1
= CreateProtocolHandler("test", "test1");
714 registry()->OnAcceptRegisterProtocolHandler(ph1
);
715 registry()->ClearDefault("test");
716 std::vector
<std::string
> handled_protocols
;
717 registry()->GetRegisteredProtocols(&handled_protocols
);
718 ASSERT_EQ(static_cast<size_t>(1), handled_protocols
.size());
719 ASSERT_EQ("test", handled_protocols
[0]);
722 TEST_F(ProtocolHandlerRegistryTest
, TestDisablePreventsHandling
) {
723 ProtocolHandler ph1
= CreateProtocolHandler("test", "test1");
724 registry()->OnAcceptRegisterProtocolHandler(ph1
);
725 ASSERT_TRUE(registry()->IsHandledProtocol("test"));
726 registry()->Disable();
727 ASSERT_FALSE(registry()->IsHandledProtocol("test"));
730 // TODO(smckay): This is much more appropriately an integration
731 // test. Make that so, then update the
732 // ShellIntegretion{Delegate,Observer,Worker} test classes we use to fully
733 // isolate this test from the FILE thread.
734 TEST_F(ProtocolHandlerRegistryTest
, TestOSRegistration
) {
735 ProtocolHandler ph_do1
= CreateProtocolHandler("do", "test1");
736 ProtocolHandler ph_do2
= CreateProtocolHandler("do", "test2");
737 ProtocolHandler ph_dont
= CreateProtocolHandler("dont", "test");
739 ASSERT_FALSE(delegate()->IsFakeRegisteredWithOS("do"));
740 ASSERT_FALSE(delegate()->IsFakeRegisteredWithOS("dont"));
742 registry()->OnAcceptRegisterProtocolHandler(ph_do1
);
743 registry()->OnDenyRegisterProtocolHandler(ph_dont
);
744 base::MessageLoop::current()->Run(); // FILE thread needs to run.
745 ASSERT_TRUE(delegate()->IsFakeRegisteredWithOS("do"));
746 ASSERT_FALSE(delegate()->IsFakeRegisteredWithOS("dont"));
748 // This should not register with the OS, if it does the delegate
749 // will assert for us. We don't need to wait for the message loop
750 // as it should not go through to the shell worker.
751 registry()->OnAcceptRegisterProtocolHandler(ph_do2
);
754 #if defined(OS_LINUX)
755 // TODO(benwells): When Linux support is more reliable and
756 // http://crbut.com/88255 is fixed this test will pass.
757 #define MAYBE_TestOSRegistrationFailure DISABLED_TestOSRegistrationFailure
759 #define MAYBE_TestOSRegistrationFailure TestOSRegistrationFailure
762 // TODO(smckay): This is much more appropriately an integration
763 // test. Make that so, then update the
764 // ShellIntegretion{Delegate,Observer,Worker} test classes we use to fully
765 // isolate this test from the FILE thread.
766 TEST_F(ProtocolHandlerRegistryTest
, MAYBE_TestOSRegistrationFailure
) {
767 ProtocolHandler ph_do
= CreateProtocolHandler("do", "test1");
768 ProtocolHandler ph_dont
= CreateProtocolHandler("dont", "test");
770 ASSERT_FALSE(registry()->IsHandledProtocol("do"));
771 ASSERT_FALSE(registry()->IsHandledProtocol("dont"));
773 registry()->OnAcceptRegisterProtocolHandler(ph_do
);
774 base::MessageLoop::current()->Run(); // FILE thread needs to run.
775 delegate()->set_force_os_failure(true);
776 registry()->OnAcceptRegisterProtocolHandler(ph_dont
);
777 base::MessageLoop::current()->Run(); // FILE thread needs to run.
778 ASSERT_TRUE(registry()->IsHandledProtocol("do"));
779 ASSERT_EQ(static_cast<size_t>(1), registry()->GetHandlersFor("do").size());
780 ASSERT_FALSE(registry()->IsHandledProtocol("dont"));
781 ASSERT_EQ(static_cast<size_t>(1), registry()->GetHandlersFor("dont").size());
784 TEST_F(ProtocolHandlerRegistryTest
, TestMaybeCreateTaskWorksFromIOThread
) {
785 ProtocolHandler ph1
= CreateProtocolHandler("mailto", "test1");
786 registry()->OnAcceptRegisterProtocolHandler(ph1
);
787 GURL
url("mailto:someone@something.com");
789 scoped_ptr
<net::URLRequestJobFactory
> interceptor(
790 registry()->CreateJobInterceptorFactory());
791 AssertIntercepted(url
, interceptor
.get());
794 TEST_F(ProtocolHandlerRegistryTest
,
795 MAYBE_TestIsHandledProtocolWorksOnIOThread
) {
796 std::string
scheme("mailto");
797 ProtocolHandler ph1
= CreateProtocolHandler(scheme
, "test1");
798 registry()->OnAcceptRegisterProtocolHandler(ph1
);
800 scoped_ptr
<ProtocolHandlerRegistry::JobInterceptorFactory
> interceptor(
801 registry()->CreateJobInterceptorFactory());
802 AssertWillHandle(scheme
, true, interceptor
.get());
805 TEST_F(ProtocolHandlerRegistryTest
, TestRemovingDefaultFallsBackToOldDefault
) {
806 ProtocolHandler ph1
= CreateProtocolHandler("mailto", "test1");
807 ProtocolHandler ph2
= CreateProtocolHandler("mailto", "test2");
808 ProtocolHandler ph3
= CreateProtocolHandler("mailto", "test3");
809 registry()->OnAcceptRegisterProtocolHandler(ph1
);
810 registry()->OnAcceptRegisterProtocolHandler(ph2
);
811 registry()->OnAcceptRegisterProtocolHandler(ph3
);
813 ASSERT_TRUE(registry()->IsDefault(ph3
));
814 registry()->RemoveHandler(ph3
);
815 ASSERT_TRUE(registry()->IsDefault(ph2
));
816 registry()->OnAcceptRegisterProtocolHandler(ph3
);
817 ASSERT_TRUE(registry()->IsDefault(ph3
));
818 registry()->RemoveHandler(ph2
);
819 ASSERT_TRUE(registry()->IsDefault(ph3
));
820 registry()->RemoveHandler(ph3
);
821 ASSERT_TRUE(registry()->IsDefault(ph1
));
824 TEST_F(ProtocolHandlerRegistryTest
, TestRemovingDefaultDoesntChangeHandlers
) {
825 ProtocolHandler ph1
= CreateProtocolHandler("mailto", "test1");
826 ProtocolHandler ph2
= CreateProtocolHandler("mailto", "test2");
827 ProtocolHandler ph3
= CreateProtocolHandler("mailto", "test3");
828 registry()->OnAcceptRegisterProtocolHandler(ph1
);
829 registry()->OnAcceptRegisterProtocolHandler(ph2
);
830 registry()->OnAcceptRegisterProtocolHandler(ph3
);
831 registry()->RemoveHandler(ph3
);
833 ProtocolHandlerRegistry::ProtocolHandlerList handlers
=
834 registry()->GetHandlersFor("mailto");
835 ASSERT_EQ(static_cast<size_t>(2), handlers
.size());
837 ASSERT_EQ(ph2
, handlers
[0]);
838 ASSERT_EQ(ph1
, handlers
[1]);
841 TEST_F(ProtocolHandlerRegistryTest
, MAYBE_TestClearDefaultGetsPropagatedToIO
) {
842 std::string
scheme("mailto");
843 ProtocolHandler ph1
= CreateProtocolHandler(scheme
, "test1");
844 registry()->OnAcceptRegisterProtocolHandler(ph1
);
845 registry()->ClearDefault(scheme
);
847 scoped_ptr
<ProtocolHandlerRegistry::JobInterceptorFactory
> interceptor(
848 registry()->CreateJobInterceptorFactory());
849 AssertWillHandle(scheme
, false, interceptor
.get());
852 TEST_F(ProtocolHandlerRegistryTest
, TestLoadEnabledGetsPropogatedToIO
) {
853 std::string
mailto("mailto");
854 ProtocolHandler ph1
= CreateProtocolHandler(mailto
, "MailtoHandler");
855 registry()->OnAcceptRegisterProtocolHandler(ph1
);
857 scoped_ptr
<ProtocolHandlerRegistry::JobInterceptorFactory
> interceptor(
858 registry()->CreateJobInterceptorFactory());
859 AssertWillHandle(mailto
, true, interceptor
.get());
860 registry()->Disable();
861 AssertWillHandle(mailto
, false, interceptor
.get());
864 TEST_F(ProtocolHandlerRegistryTest
, TestReplaceHandler
) {
865 ProtocolHandler ph1
= CreateProtocolHandler("mailto",
866 GURL("http://test.com/%s"), "test1");
867 ProtocolHandler ph2
= CreateProtocolHandler("mailto",
868 GURL("http://test.com/updated-url/%s"), "test2");
869 registry()->OnAcceptRegisterProtocolHandler(ph1
);
870 ASSERT_TRUE(registry()->AttemptReplace(ph2
));
871 const ProtocolHandler
& handler(registry()->GetHandlerFor("mailto"));
872 ASSERT_EQ(handler
.url(), ph2
.url());
875 TEST_F(ProtocolHandlerRegistryTest
, TestReplaceNonDefaultHandler
) {
876 ProtocolHandler ph1
= CreateProtocolHandler("mailto",
877 GURL("http://test.com/%s"), "test1");
878 ProtocolHandler ph2
= CreateProtocolHandler("mailto",
879 GURL("http://test.com/updated-url/%s"), "test2");
880 ProtocolHandler ph3
= CreateProtocolHandler("mailto",
881 GURL("http://else.com/%s"), "test3");
882 registry()->OnAcceptRegisterProtocolHandler(ph1
);
883 registry()->OnAcceptRegisterProtocolHandler(ph3
);
884 ASSERT_TRUE(registry()->AttemptReplace(ph2
));
885 const ProtocolHandler
& handler(registry()->GetHandlerFor("mailto"));
886 ASSERT_EQ(handler
.url(), ph3
.url());
889 TEST_F(ProtocolHandlerRegistryTest
, TestReplaceRemovesStaleHandlers
) {
890 ProtocolHandler ph1
= CreateProtocolHandler("mailto",
891 GURL("http://test.com/%s"), "test1");
892 ProtocolHandler ph2
= CreateProtocolHandler("mailto",
893 GURL("http://test.com/updated-url/%s"), "test2");
894 ProtocolHandler ph3
= CreateProtocolHandler("mailto",
895 GURL("http://test.com/third/%s"), "test");
896 registry()->OnAcceptRegisterProtocolHandler(ph1
);
897 registry()->OnAcceptRegisterProtocolHandler(ph2
);
899 // This should replace the previous two handlers.
900 ASSERT_TRUE(registry()->AttemptReplace(ph3
));
901 const ProtocolHandler
& handler(registry()->GetHandlerFor("mailto"));
902 ASSERT_EQ(handler
.url(), ph3
.url());
903 registry()->RemoveHandler(ph3
);
904 ASSERT_TRUE(registry()->GetHandlerFor("mailto").IsEmpty());
907 TEST_F(ProtocolHandlerRegistryTest
, TestIsSameOrigin
) {
908 ProtocolHandler ph1
= CreateProtocolHandler("mailto",
909 GURL("http://test.com/%s"), "test1");
910 ProtocolHandler ph2
= CreateProtocolHandler("mailto",
911 GURL("http://test.com/updated-url/%s"), "test2");
912 ProtocolHandler ph3
= CreateProtocolHandler("mailto",
913 GURL("http://other.com/%s"), "test");
914 ASSERT_EQ(ph1
.url().GetOrigin() == ph2
.url().GetOrigin(),
915 ph1
.IsSameOrigin(ph2
));
916 ASSERT_EQ(ph1
.url().GetOrigin() == ph2
.url().GetOrigin(),
917 ph2
.IsSameOrigin(ph1
));
918 ASSERT_EQ(ph2
.url().GetOrigin() == ph3
.url().GetOrigin(),
919 ph2
.IsSameOrigin(ph3
));
920 ASSERT_EQ(ph3
.url().GetOrigin() == ph2
.url().GetOrigin(),
921 ph3
.IsSameOrigin(ph2
));
924 TEST_F(ProtocolHandlerRegistryTest
, MAYBE_TestInstallDefaultHandler
) {
925 RecreateRegistry(false);
926 registry()->AddPredefinedHandler(CreateProtocolHandler(
927 "test", GURL("http://test.com/%s"), "Test"));
928 registry()->InitProtocolSettings();
929 std::vector
<std::string
> protocols
;
930 registry()->GetRegisteredProtocols(&protocols
);
931 ASSERT_EQ(static_cast<size_t>(1), protocols
.size());