1 // Copyright 2014 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 "base/at_exit.h"
7 #include "base/macros.h"
8 #include "base/memory/scoped_vector.h"
9 #include "base/message_loop/message_loop.h"
10 #include "mojo/application/public/cpp/application_connection.h"
11 #include "mojo/application/public/cpp/application_delegate.h"
12 #include "mojo/application/public/cpp/application_impl.h"
13 #include "mojo/application/public/cpp/interface_factory.h"
14 #include "mojo/application/public/interfaces/service_provider.mojom.h"
15 #include "mojo/public/cpp/bindings/strong_binding.h"
16 #include "mojo/shell/application_loader.h"
17 #include "mojo/shell/application_manager.h"
18 #include "mojo/shell/fetcher.h"
19 #include "mojo/shell/test.mojom.h"
20 #include "testing/gtest/include/gtest/gtest.h"
26 const char kTestURLString
[] = "test:testService";
27 const char kTestAURLString
[] = "test:TestA";
28 const char kTestBURLString
[] = "test:TestB";
30 const char kTestMimeType
[] = "test/mime-type";
32 class TestMimeTypeFetcher
: public Fetcher
{
34 explicit TestMimeTypeFetcher(const FetchCallback
& fetch_callback
)
35 : Fetcher(fetch_callback
), url_("xxx") {
36 loader_callback_
.Run(make_scoped_ptr(this));
38 ~TestMimeTypeFetcher() override
{}
41 const GURL
& GetURL() const override
{ return url_
; }
42 GURL
GetRedirectURL() const override
{ return GURL("yyy"); }
43 GURL
GetRedirectReferer() const override
{ return GURL(); }
44 URLResponsePtr
AsURLResponse(base::TaskRunner
* task_runner
,
45 uint32_t skip
) override
{
46 return URLResponse::New().Pass();
49 base::TaskRunner
* task_runner
,
50 base::Callback
<void(const base::FilePath
&, bool)> callback
) override
{}
51 std::string
MimeType() override
{ return kTestMimeType
; }
52 bool HasMojoMagic() override
{ return false; }
53 bool PeekFirstLine(std::string
* line
) override
{ return false; }
58 DISALLOW_COPY_AND_ASSIGN(TestMimeTypeFetcher
);
62 TestContext() : num_impls(0), num_loader_deletes(0) {}
63 std::string last_test_string
;
65 int num_loader_deletes
;
68 void QuitClosure(bool* value
) {
70 base::MessageLoop::current()->QuitWhenIdle();
73 class QuitMessageLoopErrorHandler
: public ErrorHandler
{
75 QuitMessageLoopErrorHandler() {}
76 ~QuitMessageLoopErrorHandler() override
{}
78 // |ErrorHandler| implementation:
79 void OnConnectionError() override
{
80 base::MessageLoop::current()->QuitWhenIdle();
84 DISALLOW_COPY_AND_ASSIGN(QuitMessageLoopErrorHandler
);
87 class TestServiceImpl
: public TestService
{
89 TestServiceImpl(TestContext
* context
, InterfaceRequest
<TestService
> request
)
90 : context_(context
), binding_(this, request
.Pass()) {
91 ++context_
->num_impls
;
94 ~TestServiceImpl() override
{
95 --context_
->num_impls
;
96 if (!base::MessageLoop::current()->is_running())
98 base::MessageLoop::current()->Quit();
101 // TestService implementation:
102 void Test(const String
& test_string
,
103 const Callback
<void()>& callback
) override
{
104 context_
->last_test_string
= test_string
;
109 TestContext
* context_
;
110 StrongBinding
<TestService
> binding_
;
115 explicit TestClient(TestServicePtr service
)
116 : service_(service
.Pass()), quit_after_ack_(false) {}
120 base::MessageLoop::current()->Quit();
123 void Test(const std::string
& test_string
) {
124 quit_after_ack_
= true;
125 service_
->Test(test_string
,
126 base::Bind(&TestClient::AckTest
, base::Unretained(this)));
130 TestServicePtr service_
;
131 bool quit_after_ack_
;
132 DISALLOW_COPY_AND_ASSIGN(TestClient
);
135 class TestApplicationLoader
: public ApplicationLoader
,
136 public ApplicationDelegate
,
137 public InterfaceFactory
<TestService
> {
139 TestApplicationLoader() : context_(nullptr), num_loads_(0) {}
141 ~TestApplicationLoader() override
{
143 ++context_
->num_loader_deletes
;
147 void set_context(TestContext
* context
) { context_
= context
; }
148 int num_loads() const { return num_loads_
; }
149 const GURL
& last_requestor_url() const { return last_requestor_url_
; }
152 // ApplicationLoader implementation.
153 void Load(const GURL
& url
,
154 InterfaceRequest
<Application
> application_request
) override
{
156 test_app_
.reset(new ApplicationImpl(this, application_request
.Pass()));
159 // ApplicationDelegate implementation.
160 bool ConfigureIncomingConnection(ApplicationConnection
* connection
) override
{
161 connection
->AddService(this);
162 last_requestor_url_
= GURL(connection
->GetRemoteApplicationURL());
166 // InterfaceFactory implementation.
167 void Create(ApplicationConnection
* connection
,
168 InterfaceRequest
<TestService
> request
) override
{
169 new TestServiceImpl(context_
, request
.Pass());
172 scoped_ptr
<ApplicationImpl
> test_app_
;
173 TestContext
* context_
;
175 GURL last_requestor_url_
;
177 DISALLOW_COPY_AND_ASSIGN(TestApplicationLoader
);
180 class ClosingApplicationLoader
: public ApplicationLoader
{
182 // ApplicationLoader implementation.
183 void Load(const GURL
& url
,
184 InterfaceRequest
<Application
> application_request
) override
{}
187 class TesterContext
{
189 explicit TesterContext(base::MessageLoop
* loop
)
195 tester_called_quit_(false),
196 a_called_quit_(false),
199 void IncrementNumBCalls() {
200 base::AutoLock
lock(lock_
);
204 void IncrementNumCCalls() {
205 base::AutoLock
lock(lock_
);
209 void IncrementNumADeletes() {
210 base::AutoLock
lock(lock_
);
214 void IncrementNumBDeletes() {
215 base::AutoLock
lock(lock_
);
219 void IncrementNumCDeletes() {
220 base::AutoLock
lock(lock_
);
224 void set_tester_called_quit() {
225 base::AutoLock
lock(lock_
);
226 tester_called_quit_
= true;
229 void set_a_called_quit() {
230 base::AutoLock
lock(lock_
);
231 a_called_quit_
= true;
235 base::AutoLock
lock(lock_
);
239 base::AutoLock
lock(lock_
);
242 int num_a_deletes() {
243 base::AutoLock
lock(lock_
);
244 return num_a_deletes_
;
246 int num_b_deletes() {
247 base::AutoLock
lock(lock_
);
248 return num_b_deletes_
;
250 int num_c_deletes() {
251 base::AutoLock
lock(lock_
);
252 return num_c_deletes_
;
254 bool tester_called_quit() {
255 base::AutoLock
lock(lock_
);
256 return tester_called_quit_
;
258 bool a_called_quit() {
259 base::AutoLock
lock(lock_
);
260 return a_called_quit_
;
264 loop_
->PostTask(FROM_HERE
, base::MessageLoop::QuitWhenIdleClosure());
268 // lock_ protects all members except for loop_ which must be unchanged for the
269 // lifetime of this class.
276 bool tester_called_quit_
;
279 base::MessageLoop
* loop_
;
282 // Used to test that the requestor url will be correctly passed.
283 class TestAImpl
: public TestA
{
285 TestAImpl(ApplicationImpl
* app_impl
,
286 TesterContext
* test_context
,
287 InterfaceRequest
<TestA
> request
)
288 : test_context_(test_context
), binding_(this, request
.Pass()) {
289 mojo::URLRequestPtr
request2(mojo::URLRequest::New());
290 request2
->url
= mojo::String::From(kTestBURLString
);
291 app_impl
->ConnectToApplication(request2
.Pass())->ConnectToService(&b_
);
294 ~TestAImpl() override
{
295 test_context_
->IncrementNumADeletes();
296 if (base::MessageLoop::current()->is_running())
301 void CallB() override
{
302 b_
->B(base::Bind(&TestAImpl::Quit
, base::Unretained(this)));
305 void CallCFromB() override
{
306 b_
->CallC(base::Bind(&TestAImpl::Quit
, base::Unretained(this)));
310 base::MessageLoop::current()->Quit();
311 test_context_
->set_a_called_quit();
312 test_context_
->QuitSoon();
315 TesterContext
* test_context_
;
317 StrongBinding
<TestA
> binding_
;
320 class TestBImpl
: public TestB
{
322 TestBImpl(ApplicationConnection
* connection
,
323 TesterContext
* test_context
,
324 InterfaceRequest
<TestB
> request
)
325 : test_context_(test_context
), binding_(this, request
.Pass()) {
326 connection
->ConnectToService(&c_
);
329 ~TestBImpl() override
{
330 test_context_
->IncrementNumBDeletes();
331 if (base::MessageLoop::current()->is_running())
332 base::MessageLoop::current()->Quit();
333 test_context_
->QuitSoon();
337 void B(const Callback
<void()>& callback
) override
{
338 test_context_
->IncrementNumBCalls();
342 void CallC(const Callback
<void()>& callback
) override
{
343 test_context_
->IncrementNumBCalls();
347 TesterContext
* test_context_
;
349 StrongBinding
<TestB
> binding_
;
352 class TestCImpl
: public TestC
{
354 TestCImpl(ApplicationConnection
* connection
,
355 TesterContext
* test_context
,
356 InterfaceRequest
<TestC
> request
)
357 : test_context_(test_context
), binding_(this, request
.Pass()) {}
359 ~TestCImpl() override
{ test_context_
->IncrementNumCDeletes(); }
362 void C(const Callback
<void()>& callback
) override
{
363 test_context_
->IncrementNumCCalls();
367 TesterContext
* test_context_
;
368 StrongBinding
<TestC
> binding_
;
371 class Tester
: public ApplicationDelegate
,
372 public ApplicationLoader
,
373 public InterfaceFactory
<TestA
>,
374 public InterfaceFactory
<TestB
>,
375 public InterfaceFactory
<TestC
> {
377 Tester(TesterContext
* context
, const std::string
& requestor_url
)
378 : context_(context
), requestor_url_(requestor_url
) {}
379 ~Tester() override
{}
382 void Load(const GURL
& url
,
383 InterfaceRequest
<Application
> application_request
) override
{
384 app_
.reset(new ApplicationImpl(this, application_request
.Pass()));
387 bool ConfigureIncomingConnection(ApplicationConnection
* connection
) override
{
388 if (!requestor_url_
.empty() &&
389 requestor_url_
!= connection
->GetRemoteApplicationURL()) {
390 context_
->set_tester_called_quit();
391 context_
->QuitSoon();
392 base::MessageLoop::current()->Quit();
395 // If we're coming from A, then add B, otherwise A.
396 if (connection
->GetRemoteApplicationURL() == kTestAURLString
)
397 connection
->AddService
<TestB
>(this);
399 connection
->AddService
<TestA
>(this);
403 bool ConfigureOutgoingConnection(ApplicationConnection
* connection
) override
{
404 // If we're connecting to B, then add C.
405 if (connection
->GetRemoteApplicationURL() == kTestBURLString
)
406 connection
->AddService
<TestC
>(this);
410 void Create(ApplicationConnection
* connection
,
411 InterfaceRequest
<TestA
> request
) override
{
412 a_bindings_
.push_back(new TestAImpl(app_
.get(), context_
, request
.Pass()));
415 void Create(ApplicationConnection
* connection
,
416 InterfaceRequest
<TestB
> request
) override
{
417 new TestBImpl(connection
, context_
, request
.Pass());
420 void Create(ApplicationConnection
* connection
,
421 InterfaceRequest
<TestC
> request
) override
{
422 new TestCImpl(connection
, context_
, request
.Pass());
425 TesterContext
* context_
;
426 scoped_ptr
<ApplicationImpl
> app_
;
427 std::string requestor_url_
;
428 ScopedVector
<TestAImpl
> a_bindings_
;
431 class TestDelegate
: public ApplicationManager::Delegate
{
433 TestDelegate() : create_test_fetcher_(false) {}
434 ~TestDelegate() override
{}
436 void AddMapping(const GURL
& from
, const GURL
& to
) { mappings_
[from
] = to
; }
438 void set_create_test_fetcher(bool create_test_fetcher
) {
439 create_test_fetcher_
= create_test_fetcher
;
442 // ApplicationManager::Delegate
443 GURL
ResolveMappings(const GURL
& url
) override
{
444 auto it
= mappings_
.find(url
);
445 if (it
!= mappings_
.end())
449 GURL
ResolveMojoURL(const GURL
& url
) override
{
450 GURL mapped_url
= ResolveMappings(url
);
451 // The shell automatically map mojo URLs.
452 if (mapped_url
.scheme() == "mojo") {
453 url::Replacements
<char> replacements
;
454 replacements
.SetScheme("file", url::Component(0, 4));
455 mapped_url
= mapped_url
.ReplaceComponents(replacements
);
459 bool CreateFetcher(const GURL
& url
,
460 const Fetcher::FetchCallback
& loader_callback
) override
{
461 if (!create_test_fetcher_
)
463 new TestMimeTypeFetcher(loader_callback
);
468 std::map
<GURL
, GURL
> mappings_
;
469 bool create_test_fetcher_
;
471 DISALLOW_COPY_AND_ASSIGN(TestDelegate
);
474 class ApplicationManagerTest
: public testing::Test
{
476 ApplicationManagerTest() : tester_context_(&loop_
) {}
478 ~ApplicationManagerTest() override
{}
480 void SetUp() override
{
481 application_manager_
.reset(new ApplicationManager(&test_delegate_
));
482 test_loader_
= new TestApplicationLoader
;
483 test_loader_
->set_context(&context_
);
484 application_manager_
->set_default_loader(
485 scoped_ptr
<ApplicationLoader
>(test_loader_
));
487 TestServicePtr service_proxy
;
488 application_manager_
->ConnectToService(GURL(kTestURLString
),
490 test_client_
.reset(new TestClient(service_proxy
.Pass()));
493 void TearDown() override
{
494 test_client_
.reset();
495 application_manager_
.reset();
498 void AddLoaderForURL(const GURL
& url
, const std::string
& requestor_url
) {
499 application_manager_
->SetLoaderForURL(
500 make_scoped_ptr(new Tester(&tester_context_
, requestor_url
)), url
);
503 bool HasFactoryForURL(const GURL
& url
) {
504 ApplicationManager::TestAPI
manager_test_api(application_manager_
.get());
505 return manager_test_api
.HasFactoryForURL(url
);
509 base::ShadowingAtExitManager at_exit_
;
510 TestDelegate test_delegate_
;
511 TestApplicationLoader
* test_loader_
;
512 TesterContext tester_context_
;
513 TestContext context_
;
514 base::MessageLoop loop_
;
515 scoped_ptr
<TestClient
> test_client_
;
516 scoped_ptr
<ApplicationManager
> application_manager_
;
517 DISALLOW_COPY_AND_ASSIGN(ApplicationManagerTest
);
520 TEST_F(ApplicationManagerTest
, Basic
) {
521 test_client_
->Test("test");
523 EXPECT_EQ(std::string("test"), context_
.last_test_string
);
526 // Confirm that url mappings are respected.
527 TEST_F(ApplicationManagerTest
, URLMapping
) {
528 ApplicationManager
am(&test_delegate_
);
529 GURL
test_url("test:test");
530 GURL
test_url2("test:test2");
531 test_delegate_
.AddMapping(test_url
, test_url2
);
532 TestApplicationLoader
* loader
= new TestApplicationLoader
;
533 loader
->set_context(&context_
);
534 am
.SetLoaderForURL(scoped_ptr
<ApplicationLoader
>(loader
), test_url2
);
536 // Connext to the mapped url
537 TestServicePtr test_service
;
538 am
.ConnectToService(test_url
, &test_service
);
539 TestClient
test_client(test_service
.Pass());
540 test_client
.Test("test");
544 // Connext to the target url
545 TestServicePtr test_service
;
546 am
.ConnectToService(test_url2
, &test_service
);
547 TestClient
test_client(test_service
.Pass());
548 test_client
.Test("test");
553 TEST_F(ApplicationManagerTest
, ClientError
) {
554 test_client_
->Test("test");
555 EXPECT_TRUE(HasFactoryForURL(GURL(kTestURLString
)));
557 EXPECT_EQ(1, context_
.num_impls
);
558 test_client_
.reset();
560 EXPECT_EQ(0, context_
.num_impls
);
561 EXPECT_TRUE(HasFactoryForURL(GURL(kTestURLString
)));
564 TEST_F(ApplicationManagerTest
, Deletes
) {
566 ApplicationManager
am(&test_delegate_
);
567 TestApplicationLoader
* default_loader
= new TestApplicationLoader
;
568 default_loader
->set_context(&context_
);
569 TestApplicationLoader
* url_loader1
= new TestApplicationLoader
;
570 TestApplicationLoader
* url_loader2
= new TestApplicationLoader
;
571 url_loader1
->set_context(&context_
);
572 url_loader2
->set_context(&context_
);
573 TestApplicationLoader
* scheme_loader1
= new TestApplicationLoader
;
574 TestApplicationLoader
* scheme_loader2
= new TestApplicationLoader
;
575 scheme_loader1
->set_context(&context_
);
576 scheme_loader2
->set_context(&context_
);
577 am
.set_default_loader(scoped_ptr
<ApplicationLoader
>(default_loader
));
578 am
.SetLoaderForURL(scoped_ptr
<ApplicationLoader
>(url_loader1
),
580 am
.SetLoaderForURL(scoped_ptr
<ApplicationLoader
>(url_loader2
),
582 am
.SetLoaderForScheme(scoped_ptr
<ApplicationLoader
>(scheme_loader1
),
584 am
.SetLoaderForScheme(scoped_ptr
<ApplicationLoader
>(scheme_loader2
),
587 EXPECT_EQ(5, context_
.num_loader_deletes
);
590 // Confirm that both urls and schemes can have their loaders explicitly set.
591 TEST_F(ApplicationManagerTest
, SetLoaders
) {
592 TestApplicationLoader
* default_loader
= new TestApplicationLoader
;
593 TestApplicationLoader
* url_loader
= new TestApplicationLoader
;
594 TestApplicationLoader
* scheme_loader
= new TestApplicationLoader
;
595 application_manager_
->set_default_loader(
596 scoped_ptr
<ApplicationLoader
>(default_loader
));
597 application_manager_
->SetLoaderForURL(
598 scoped_ptr
<ApplicationLoader
>(url_loader
), GURL("test:test1"));
599 application_manager_
->SetLoaderForScheme(
600 scoped_ptr
<ApplicationLoader
>(scheme_loader
), "test");
602 // test::test1 should go to url_loader.
603 TestServicePtr test_service
;
604 application_manager_
->ConnectToService(GURL("test:test1"), &test_service
);
605 EXPECT_EQ(1, url_loader
->num_loads());
606 EXPECT_EQ(0, scheme_loader
->num_loads());
607 EXPECT_EQ(0, default_loader
->num_loads());
609 // test::test2 should go to scheme loader.
610 application_manager_
->ConnectToService(GURL("test:test2"), &test_service
);
611 EXPECT_EQ(1, url_loader
->num_loads());
612 EXPECT_EQ(1, scheme_loader
->num_loads());
613 EXPECT_EQ(0, default_loader
->num_loads());
615 // http::test1 should go to default loader.
616 application_manager_
->ConnectToService(GURL("http:test1"), &test_service
);
617 EXPECT_EQ(1, url_loader
->num_loads());
618 EXPECT_EQ(1, scheme_loader
->num_loads());
619 EXPECT_EQ(1, default_loader
->num_loads());
622 // Confirm that the url of a service is correctly passed to another service that
624 TEST_F(ApplicationManagerTest
, ACallB
) {
625 // Any url can load a.
626 AddLoaderForURL(GURL(kTestAURLString
), std::string());
628 // Only a can load b.
629 AddLoaderForURL(GURL(kTestBURLString
), kTestAURLString
);
632 application_manager_
->ConnectToService(GURL(kTestAURLString
), &a
);
635 EXPECT_EQ(1, tester_context_
.num_b_calls());
636 EXPECT_TRUE(tester_context_
.a_called_quit());
639 // A calls B which calls C.
640 TEST_F(ApplicationManagerTest
, BCallC
) {
641 // Any url can load a.
642 AddLoaderForURL(GURL(kTestAURLString
), std::string());
644 // Only a can load b.
645 AddLoaderForURL(GURL(kTestBURLString
), kTestAURLString
);
648 application_manager_
->ConnectToService(GURL(kTestAURLString
), &a
);
652 EXPECT_EQ(1, tester_context_
.num_b_calls());
653 EXPECT_EQ(1, tester_context_
.num_c_calls());
654 EXPECT_TRUE(tester_context_
.a_called_quit());
657 // Confirm that a service impl will be deleted if the app that connected to
659 TEST_F(ApplicationManagerTest
, BDeleted
) {
660 AddLoaderForURL(GURL(kTestAURLString
), std::string());
661 AddLoaderForURL(GURL(kTestBURLString
), std::string());
664 application_manager_
->ConnectToService(GURL(kTestAURLString
), &a
);
670 application_manager_
->SetLoaderForURL(scoped_ptr
<ApplicationLoader
>(),
671 GURL(kTestAURLString
));
674 EXPECT_EQ(1, tester_context_
.num_b_deletes());
677 // Confirm that the url of a service is correctly passed to another service that
678 // it loads, and that it can be rejected.
679 TEST_F(ApplicationManagerTest
, ANoLoadB
) {
680 // Any url can load a.
681 AddLoaderForURL(GURL(kTestAURLString
), std::string());
683 // Only c can load b, so this will fail.
684 AddLoaderForURL(GURL(kTestBURLString
), "test:TestC");
687 application_manager_
->ConnectToService(GURL(kTestAURLString
), &a
);
690 EXPECT_EQ(0, tester_context_
.num_b_calls());
692 EXPECT_FALSE(tester_context_
.a_called_quit());
693 EXPECT_TRUE(tester_context_
.tester_called_quit());
696 TEST_F(ApplicationManagerTest
, NoServiceNoLoad
) {
697 AddLoaderForURL(GURL(kTestAURLString
), std::string());
699 // There is no TestC service implementation registered with
700 // ApplicationManager, so this cannot succeed (but also shouldn't crash).
702 application_manager_
->ConnectToService(GURL(kTestAURLString
), &c
);
703 QuitMessageLoopErrorHandler quitter
;
704 c
.set_error_handler(&quitter
);
707 EXPECT_TRUE(c
.encountered_error());
710 TEST_F(ApplicationManagerTest
, MappedURLsShouldNotCauseDuplicateLoad
) {
711 test_delegate_
.AddMapping(GURL("foo:foo2"), GURL("foo:foo"));
712 // 1 because ApplicationManagerTest connects once at startup.
713 EXPECT_EQ(1, test_loader_
->num_loads());
715 TestServicePtr test_service
;
716 application_manager_
->ConnectToService(GURL("foo:foo"), &test_service
);
717 EXPECT_EQ(2, test_loader_
->num_loads());
719 TestServicePtr test_service2
;
720 application_manager_
->ConnectToService(GURL("foo:foo2"), &test_service2
);
721 EXPECT_EQ(2, test_loader_
->num_loads());
723 TestServicePtr test_service3
;
724 application_manager_
->ConnectToService(GURL("bar:bar"), &test_service2
);
725 EXPECT_EQ(3, test_loader_
->num_loads());
728 TEST_F(ApplicationManagerTest
, MappedURLsShouldWorkWithLoaders
) {
729 TestApplicationLoader
* custom_loader
= new TestApplicationLoader
;
731 custom_loader
->set_context(&context
);
732 application_manager_
->SetLoaderForURL(make_scoped_ptr(custom_loader
),
734 test_delegate_
.AddMapping(GURL("mojo:foo2"), GURL("mojo:foo"));
736 TestServicePtr test_service
;
737 application_manager_
->ConnectToService(GURL("mojo:foo2"), &test_service
);
738 EXPECT_EQ(1, custom_loader
->num_loads());
739 custom_loader
->set_context(nullptr);
741 EXPECT_TRUE(HasFactoryForURL(GURL("mojo:foo2")));
742 EXPECT_FALSE(HasFactoryForURL(GURL("mojo:foo")));
745 TEST_F(ApplicationManagerTest
, TestQueryWithLoaders
) {
746 TestApplicationLoader
* url_loader
= new TestApplicationLoader
;
747 TestApplicationLoader
* scheme_loader
= new TestApplicationLoader
;
748 application_manager_
->SetLoaderForURL(
749 scoped_ptr
<ApplicationLoader
>(url_loader
), GURL("test:test1"));
750 application_manager_
->SetLoaderForScheme(
751 scoped_ptr
<ApplicationLoader
>(scheme_loader
), "test");
753 // test::test1 should go to url_loader.
754 TestServicePtr test_service
;
755 application_manager_
->ConnectToService(GURL("test:test1?foo=bar"),
757 EXPECT_EQ(1, url_loader
->num_loads());
758 EXPECT_EQ(0, scheme_loader
->num_loads());
760 // test::test2 should go to scheme loader.
761 application_manager_
->ConnectToService(GURL("test:test2?foo=bar"),
763 EXPECT_EQ(1, url_loader
->num_loads());
764 EXPECT_EQ(1, scheme_loader
->num_loads());
767 TEST_F(ApplicationManagerTest
, TestEndApplicationClosure
) {
768 ClosingApplicationLoader
* loader
= new ClosingApplicationLoader();
769 application_manager_
->SetLoaderForScheme(
770 scoped_ptr
<ApplicationLoader
>(loader
), "test");
773 mojo::URLRequestPtr
request(mojo::URLRequest::New());
774 request
->url
= mojo::String::From("test:test");
775 application_manager_
->ConnectToApplication(
776 request
.Pass(), GURL(), nullptr, nullptr,
777 base::Bind(&QuitClosure
, base::Unretained(&called
)));
782 TEST(ApplicationManagerTest2
, ContentHandlerConnectionGetsRequestorURL
) {
783 const GURL
content_handler_url("http://test.content.handler");
784 const GURL
requestor_url("http://requestor.url");
785 TestContext test_context
;
786 base::MessageLoop loop
;
787 TestDelegate test_delegate
;
788 test_delegate
.set_create_test_fetcher(true);
789 ApplicationManager
application_manager(&test_delegate
);
790 application_manager
.set_default_loader(nullptr);
791 application_manager
.RegisterContentHandler(kTestMimeType
,
792 content_handler_url
);
794 TestApplicationLoader
* loader
= new TestApplicationLoader
;
795 loader
->set_context(&test_context
);
796 application_manager
.SetLoaderForURL(scoped_ptr
<ApplicationLoader
>(loader
),
797 content_handler_url
);
800 mojo::URLRequestPtr
request(mojo::URLRequest::New());
801 request
->url
= mojo::String::From("test:test");
802 application_manager
.ConnectToApplication(
803 request
.Pass(), requestor_url
, nullptr, nullptr,
804 base::Bind(&QuitClosure
, base::Unretained(&called
)));
808 ASSERT_EQ(1, loader
->num_loads());
809 EXPECT_EQ(requestor_url
, loader
->last_requestor_url());