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 TestServiceImpl
: public TestService
{
75 TestServiceImpl(TestContext
* context
, InterfaceRequest
<TestService
> request
)
76 : context_(context
), binding_(this, request
.Pass()) {
77 ++context_
->num_impls
;
80 ~TestServiceImpl() override
{
81 --context_
->num_impls
;
82 if (!base::MessageLoop::current()->is_running())
84 base::MessageLoop::current()->Quit();
87 // TestService implementation:
88 void Test(const String
& test_string
,
89 const Callback
<void()>& callback
) override
{
90 context_
->last_test_string
= test_string
;
95 TestContext
* context_
;
96 StrongBinding
<TestService
> binding_
;
101 explicit TestClient(TestServicePtr service
)
102 : service_(service
.Pass()), quit_after_ack_(false) {}
106 base::MessageLoop::current()->Quit();
109 void Test(const std::string
& test_string
) {
110 quit_after_ack_
= true;
111 service_
->Test(test_string
,
112 base::Bind(&TestClient::AckTest
, base::Unretained(this)));
116 TestServicePtr service_
;
117 bool quit_after_ack_
;
118 DISALLOW_COPY_AND_ASSIGN(TestClient
);
121 class TestApplicationLoader
: public ApplicationLoader
,
122 public ApplicationDelegate
,
123 public InterfaceFactory
<TestService
> {
125 TestApplicationLoader() : context_(nullptr), num_loads_(0) {}
127 ~TestApplicationLoader() override
{
129 ++context_
->num_loader_deletes
;
133 void set_context(TestContext
* context
) { context_
= context
; }
134 int num_loads() const { return num_loads_
; }
135 const GURL
& last_requestor_url() const { return last_requestor_url_
; }
138 // ApplicationLoader implementation.
139 void Load(const GURL
& url
,
140 InterfaceRequest
<Application
> application_request
) override
{
142 test_app_
.reset(new ApplicationImpl(this, application_request
.Pass()));
145 // ApplicationDelegate implementation.
146 bool ConfigureIncomingConnection(ApplicationConnection
* connection
) override
{
147 connection
->AddService(this);
148 last_requestor_url_
= GURL(connection
->GetRemoteApplicationURL());
152 // InterfaceFactory implementation.
153 void Create(ApplicationConnection
* connection
,
154 InterfaceRequest
<TestService
> request
) override
{
155 new TestServiceImpl(context_
, request
.Pass());
158 scoped_ptr
<ApplicationImpl
> test_app_
;
159 TestContext
* context_
;
161 GURL last_requestor_url_
;
163 DISALLOW_COPY_AND_ASSIGN(TestApplicationLoader
);
166 class ClosingApplicationLoader
: public ApplicationLoader
{
168 // ApplicationLoader implementation.
169 void Load(const GURL
& url
,
170 InterfaceRequest
<Application
> application_request
) override
{}
173 class TesterContext
{
175 explicit TesterContext(base::MessageLoop
* loop
)
181 tester_called_quit_(false),
182 a_called_quit_(false),
185 void IncrementNumBCalls() {
186 base::AutoLock
lock(lock_
);
190 void IncrementNumCCalls() {
191 base::AutoLock
lock(lock_
);
195 void IncrementNumADeletes() {
196 base::AutoLock
lock(lock_
);
200 void IncrementNumBDeletes() {
201 base::AutoLock
lock(lock_
);
205 void IncrementNumCDeletes() {
206 base::AutoLock
lock(lock_
);
210 void set_tester_called_quit() {
211 base::AutoLock
lock(lock_
);
212 tester_called_quit_
= true;
215 void set_a_called_quit() {
216 base::AutoLock
lock(lock_
);
217 a_called_quit_
= true;
221 base::AutoLock
lock(lock_
);
225 base::AutoLock
lock(lock_
);
228 int num_a_deletes() {
229 base::AutoLock
lock(lock_
);
230 return num_a_deletes_
;
232 int num_b_deletes() {
233 base::AutoLock
lock(lock_
);
234 return num_b_deletes_
;
236 int num_c_deletes() {
237 base::AutoLock
lock(lock_
);
238 return num_c_deletes_
;
240 bool tester_called_quit() {
241 base::AutoLock
lock(lock_
);
242 return tester_called_quit_
;
244 bool a_called_quit() {
245 base::AutoLock
lock(lock_
);
246 return a_called_quit_
;
250 loop_
->PostTask(FROM_HERE
, base::MessageLoop::QuitWhenIdleClosure());
254 // lock_ protects all members except for loop_ which must be unchanged for the
255 // lifetime of this class.
262 bool tester_called_quit_
;
265 base::MessageLoop
* loop_
;
268 // Used to test that the requestor url will be correctly passed.
269 class TestAImpl
: public TestA
{
271 TestAImpl(ApplicationImpl
* app_impl
,
272 TesterContext
* test_context
,
273 InterfaceRequest
<TestA
> request
)
274 : test_context_(test_context
), binding_(this, request
.Pass()) {
275 mojo::URLRequestPtr
request2(mojo::URLRequest::New());
276 request2
->url
= mojo::String::From(kTestBURLString
);
277 app_impl
->ConnectToApplication(request2
.Pass())->ConnectToService(&b_
);
280 ~TestAImpl() override
{
281 test_context_
->IncrementNumADeletes();
282 if (base::MessageLoop::current()->is_running())
287 void CallB() override
{
288 b_
->B(base::Bind(&TestAImpl::Quit
, base::Unretained(this)));
291 void CallCFromB() override
{
292 b_
->CallC(base::Bind(&TestAImpl::Quit
, base::Unretained(this)));
296 base::MessageLoop::current()->Quit();
297 test_context_
->set_a_called_quit();
298 test_context_
->QuitSoon();
301 TesterContext
* test_context_
;
303 StrongBinding
<TestA
> binding_
;
306 class TestBImpl
: public TestB
{
308 TestBImpl(ApplicationConnection
* connection
,
309 TesterContext
* test_context
,
310 InterfaceRequest
<TestB
> request
)
311 : test_context_(test_context
), binding_(this, request
.Pass()) {
312 connection
->ConnectToService(&c_
);
315 ~TestBImpl() override
{
316 test_context_
->IncrementNumBDeletes();
317 if (base::MessageLoop::current()->is_running())
318 base::MessageLoop::current()->Quit();
319 test_context_
->QuitSoon();
323 void B(const Callback
<void()>& callback
) override
{
324 test_context_
->IncrementNumBCalls();
328 void CallC(const Callback
<void()>& callback
) override
{
329 test_context_
->IncrementNumBCalls();
333 TesterContext
* test_context_
;
335 StrongBinding
<TestB
> binding_
;
338 class TestCImpl
: public TestC
{
340 TestCImpl(ApplicationConnection
* connection
,
341 TesterContext
* test_context
,
342 InterfaceRequest
<TestC
> request
)
343 : test_context_(test_context
), binding_(this, request
.Pass()) {}
345 ~TestCImpl() override
{ test_context_
->IncrementNumCDeletes(); }
348 void C(const Callback
<void()>& callback
) override
{
349 test_context_
->IncrementNumCCalls();
353 TesterContext
* test_context_
;
354 StrongBinding
<TestC
> binding_
;
357 class Tester
: public ApplicationDelegate
,
358 public ApplicationLoader
,
359 public InterfaceFactory
<TestA
>,
360 public InterfaceFactory
<TestB
>,
361 public InterfaceFactory
<TestC
> {
363 Tester(TesterContext
* context
, const std::string
& requestor_url
)
364 : context_(context
), requestor_url_(requestor_url
) {}
365 ~Tester() override
{}
368 void Load(const GURL
& url
,
369 InterfaceRequest
<Application
> application_request
) override
{
370 app_
.reset(new ApplicationImpl(this, application_request
.Pass()));
373 bool ConfigureIncomingConnection(ApplicationConnection
* connection
) override
{
374 if (!requestor_url_
.empty() &&
375 requestor_url_
!= connection
->GetRemoteApplicationURL()) {
376 context_
->set_tester_called_quit();
377 context_
->QuitSoon();
378 base::MessageLoop::current()->Quit();
381 // If we're coming from A, then add B, otherwise A.
382 if (connection
->GetRemoteApplicationURL() == kTestAURLString
)
383 connection
->AddService
<TestB
>(this);
385 connection
->AddService
<TestA
>(this);
389 bool ConfigureOutgoingConnection(ApplicationConnection
* connection
) override
{
390 // If we're connecting to B, then add C.
391 if (connection
->GetRemoteApplicationURL() == kTestBURLString
)
392 connection
->AddService
<TestC
>(this);
396 void Create(ApplicationConnection
* connection
,
397 InterfaceRequest
<TestA
> request
) override
{
398 a_bindings_
.push_back(new TestAImpl(app_
.get(), context_
, request
.Pass()));
401 void Create(ApplicationConnection
* connection
,
402 InterfaceRequest
<TestB
> request
) override
{
403 new TestBImpl(connection
, context_
, request
.Pass());
406 void Create(ApplicationConnection
* connection
,
407 InterfaceRequest
<TestC
> request
) override
{
408 new TestCImpl(connection
, context_
, request
.Pass());
411 TesterContext
* context_
;
412 scoped_ptr
<ApplicationImpl
> app_
;
413 std::string requestor_url_
;
414 ScopedVector
<TestAImpl
> a_bindings_
;
417 class TestDelegate
: public ApplicationManager::Delegate
{
419 TestDelegate() : create_test_fetcher_(false) {}
420 ~TestDelegate() override
{}
422 void AddMapping(const GURL
& from
, const GURL
& to
) { mappings_
[from
] = to
; }
424 void set_create_test_fetcher(bool create_test_fetcher
) {
425 create_test_fetcher_
= create_test_fetcher
;
428 // ApplicationManager::Delegate
429 GURL
ResolveMappings(const GURL
& url
) override
{
430 auto it
= mappings_
.find(url
);
431 if (it
!= mappings_
.end())
435 GURL
ResolveMojoURL(const GURL
& url
) override
{
436 GURL mapped_url
= ResolveMappings(url
);
437 // The shell automatically map mojo URLs.
438 if (mapped_url
.scheme() == "mojo") {
439 url::Replacements
<char> replacements
;
440 replacements
.SetScheme("file", url::Component(0, 4));
441 mapped_url
= mapped_url
.ReplaceComponents(replacements
);
445 bool CreateFetcher(const GURL
& url
,
446 const Fetcher::FetchCallback
& loader_callback
) override
{
447 if (!create_test_fetcher_
)
449 new TestMimeTypeFetcher(loader_callback
);
454 std::map
<GURL
, GURL
> mappings_
;
455 bool create_test_fetcher_
;
457 DISALLOW_COPY_AND_ASSIGN(TestDelegate
);
460 class ApplicationManagerTest
: public testing::Test
{
462 ApplicationManagerTest() : tester_context_(&loop_
) {}
464 ~ApplicationManagerTest() override
{}
466 void SetUp() override
{
467 application_manager_
.reset(new ApplicationManager(&test_delegate_
));
468 test_loader_
= new TestApplicationLoader
;
469 test_loader_
->set_context(&context_
);
470 application_manager_
->set_default_loader(
471 scoped_ptr
<ApplicationLoader
>(test_loader_
));
473 TestServicePtr service_proxy
;
474 application_manager_
->ConnectToService(GURL(kTestURLString
),
476 test_client_
.reset(new TestClient(service_proxy
.Pass()));
479 void TearDown() override
{
480 test_client_
.reset();
481 application_manager_
.reset();
484 void AddLoaderForURL(const GURL
& url
, const std::string
& requestor_url
) {
485 application_manager_
->SetLoaderForURL(
486 make_scoped_ptr(new Tester(&tester_context_
, requestor_url
)), url
);
489 bool HasFactoryForURL(const GURL
& url
) {
490 ApplicationManager::TestAPI
manager_test_api(application_manager_
.get());
491 return manager_test_api
.HasFactoryForURL(url
);
495 base::ShadowingAtExitManager at_exit_
;
496 TestDelegate test_delegate_
;
497 TestApplicationLoader
* test_loader_
;
498 TesterContext tester_context_
;
499 TestContext context_
;
500 base::MessageLoop loop_
;
501 scoped_ptr
<TestClient
> test_client_
;
502 scoped_ptr
<ApplicationManager
> application_manager_
;
503 DISALLOW_COPY_AND_ASSIGN(ApplicationManagerTest
);
506 TEST_F(ApplicationManagerTest
, Basic
) {
507 test_client_
->Test("test");
509 EXPECT_EQ(std::string("test"), context_
.last_test_string
);
512 // Confirm that url mappings are respected.
513 TEST_F(ApplicationManagerTest
, URLMapping
) {
514 ApplicationManager
am(&test_delegate_
);
515 GURL
test_url("test:test");
516 GURL
test_url2("test:test2");
517 test_delegate_
.AddMapping(test_url
, test_url2
);
518 TestApplicationLoader
* loader
= new TestApplicationLoader
;
519 loader
->set_context(&context_
);
520 am
.SetLoaderForURL(scoped_ptr
<ApplicationLoader
>(loader
), test_url2
);
522 // Connext to the mapped url
523 TestServicePtr test_service
;
524 am
.ConnectToService(test_url
, &test_service
);
525 TestClient
test_client(test_service
.Pass());
526 test_client
.Test("test");
530 // Connext to the target url
531 TestServicePtr test_service
;
532 am
.ConnectToService(test_url2
, &test_service
);
533 TestClient
test_client(test_service
.Pass());
534 test_client
.Test("test");
539 TEST_F(ApplicationManagerTest
, ClientError
) {
540 test_client_
->Test("test");
541 EXPECT_TRUE(HasFactoryForURL(GURL(kTestURLString
)));
543 EXPECT_EQ(1, context_
.num_impls
);
544 test_client_
.reset();
546 EXPECT_EQ(0, context_
.num_impls
);
547 EXPECT_TRUE(HasFactoryForURL(GURL(kTestURLString
)));
550 TEST_F(ApplicationManagerTest
, Deletes
) {
552 ApplicationManager
am(&test_delegate_
);
553 TestApplicationLoader
* default_loader
= new TestApplicationLoader
;
554 default_loader
->set_context(&context_
);
555 TestApplicationLoader
* url_loader1
= new TestApplicationLoader
;
556 TestApplicationLoader
* url_loader2
= new TestApplicationLoader
;
557 url_loader1
->set_context(&context_
);
558 url_loader2
->set_context(&context_
);
559 TestApplicationLoader
* scheme_loader1
= new TestApplicationLoader
;
560 TestApplicationLoader
* scheme_loader2
= new TestApplicationLoader
;
561 scheme_loader1
->set_context(&context_
);
562 scheme_loader2
->set_context(&context_
);
563 am
.set_default_loader(scoped_ptr
<ApplicationLoader
>(default_loader
));
564 am
.SetLoaderForURL(scoped_ptr
<ApplicationLoader
>(url_loader1
),
566 am
.SetLoaderForURL(scoped_ptr
<ApplicationLoader
>(url_loader2
),
568 am
.SetLoaderForScheme(scoped_ptr
<ApplicationLoader
>(scheme_loader1
),
570 am
.SetLoaderForScheme(scoped_ptr
<ApplicationLoader
>(scheme_loader2
),
573 EXPECT_EQ(5, context_
.num_loader_deletes
);
576 // Confirm that both urls and schemes can have their loaders explicitly set.
577 TEST_F(ApplicationManagerTest
, SetLoaders
) {
578 TestApplicationLoader
* default_loader
= new TestApplicationLoader
;
579 TestApplicationLoader
* url_loader
= new TestApplicationLoader
;
580 TestApplicationLoader
* scheme_loader
= new TestApplicationLoader
;
581 application_manager_
->set_default_loader(
582 scoped_ptr
<ApplicationLoader
>(default_loader
));
583 application_manager_
->SetLoaderForURL(
584 scoped_ptr
<ApplicationLoader
>(url_loader
), GURL("test:test1"));
585 application_manager_
->SetLoaderForScheme(
586 scoped_ptr
<ApplicationLoader
>(scheme_loader
), "test");
588 // test::test1 should go to url_loader.
589 TestServicePtr test_service
;
590 application_manager_
->ConnectToService(GURL("test:test1"), &test_service
);
591 EXPECT_EQ(1, url_loader
->num_loads());
592 EXPECT_EQ(0, scheme_loader
->num_loads());
593 EXPECT_EQ(0, default_loader
->num_loads());
595 // test::test2 should go to scheme loader.
596 application_manager_
->ConnectToService(GURL("test:test2"), &test_service
);
597 EXPECT_EQ(1, url_loader
->num_loads());
598 EXPECT_EQ(1, scheme_loader
->num_loads());
599 EXPECT_EQ(0, default_loader
->num_loads());
601 // http::test1 should go to default loader.
602 application_manager_
->ConnectToService(GURL("http:test1"), &test_service
);
603 EXPECT_EQ(1, url_loader
->num_loads());
604 EXPECT_EQ(1, scheme_loader
->num_loads());
605 EXPECT_EQ(1, default_loader
->num_loads());
608 // Confirm that the url of a service is correctly passed to another service that
610 TEST_F(ApplicationManagerTest
, ACallB
) {
611 // Any url can load a.
612 AddLoaderForURL(GURL(kTestAURLString
), std::string());
614 // Only a can load b.
615 AddLoaderForURL(GURL(kTestBURLString
), kTestAURLString
);
618 application_manager_
->ConnectToService(GURL(kTestAURLString
), &a
);
621 EXPECT_EQ(1, tester_context_
.num_b_calls());
622 EXPECT_TRUE(tester_context_
.a_called_quit());
625 // A calls B which calls C.
626 TEST_F(ApplicationManagerTest
, BCallC
) {
627 // Any url can load a.
628 AddLoaderForURL(GURL(kTestAURLString
), std::string());
630 // Only a can load b.
631 AddLoaderForURL(GURL(kTestBURLString
), kTestAURLString
);
634 application_manager_
->ConnectToService(GURL(kTestAURLString
), &a
);
638 EXPECT_EQ(1, tester_context_
.num_b_calls());
639 EXPECT_EQ(1, tester_context_
.num_c_calls());
640 EXPECT_TRUE(tester_context_
.a_called_quit());
643 // Confirm that a service impl will be deleted if the app that connected to
645 TEST_F(ApplicationManagerTest
, BDeleted
) {
646 AddLoaderForURL(GURL(kTestAURLString
), std::string());
647 AddLoaderForURL(GURL(kTestBURLString
), std::string());
650 application_manager_
->ConnectToService(GURL(kTestAURLString
), &a
);
656 application_manager_
->SetLoaderForURL(scoped_ptr
<ApplicationLoader
>(),
657 GURL(kTestAURLString
));
660 EXPECT_EQ(1, tester_context_
.num_b_deletes());
663 // Confirm that the url of a service is correctly passed to another service that
664 // it loads, and that it can be rejected.
665 TEST_F(ApplicationManagerTest
, ANoLoadB
) {
666 // Any url can load a.
667 AddLoaderForURL(GURL(kTestAURLString
), std::string());
669 // Only c can load b, so this will fail.
670 AddLoaderForURL(GURL(kTestBURLString
), "test:TestC");
673 application_manager_
->ConnectToService(GURL(kTestAURLString
), &a
);
676 EXPECT_EQ(0, tester_context_
.num_b_calls());
678 EXPECT_FALSE(tester_context_
.a_called_quit());
679 EXPECT_TRUE(tester_context_
.tester_called_quit());
682 TEST_F(ApplicationManagerTest
, NoServiceNoLoad
) {
683 AddLoaderForURL(GURL(kTestAURLString
), std::string());
685 // There is no TestC service implementation registered with
686 // ApplicationManager, so this cannot succeed (but also shouldn't crash).
688 application_manager_
->ConnectToService(GURL(kTestAURLString
), &c
);
689 c
.set_connection_error_handler(
690 []() { base::MessageLoop::current()->QuitWhenIdle(); });
693 EXPECT_TRUE(c
.encountered_error());
696 TEST_F(ApplicationManagerTest
, MappedURLsShouldNotCauseDuplicateLoad
) {
697 test_delegate_
.AddMapping(GURL("foo:foo2"), GURL("foo:foo"));
698 // 1 because ApplicationManagerTest connects once at startup.
699 EXPECT_EQ(1, test_loader_
->num_loads());
701 TestServicePtr test_service
;
702 application_manager_
->ConnectToService(GURL("foo:foo"), &test_service
);
703 EXPECT_EQ(2, test_loader_
->num_loads());
705 TestServicePtr test_service2
;
706 application_manager_
->ConnectToService(GURL("foo:foo2"), &test_service2
);
707 EXPECT_EQ(2, test_loader_
->num_loads());
709 TestServicePtr test_service3
;
710 application_manager_
->ConnectToService(GURL("bar:bar"), &test_service2
);
711 EXPECT_EQ(3, test_loader_
->num_loads());
714 TEST_F(ApplicationManagerTest
, MappedURLsShouldWorkWithLoaders
) {
715 TestApplicationLoader
* custom_loader
= new TestApplicationLoader
;
717 custom_loader
->set_context(&context
);
718 application_manager_
->SetLoaderForURL(make_scoped_ptr(custom_loader
),
720 test_delegate_
.AddMapping(GURL("mojo:foo2"), GURL("mojo:foo"));
722 TestServicePtr test_service
;
723 application_manager_
->ConnectToService(GURL("mojo:foo2"), &test_service
);
724 EXPECT_EQ(1, custom_loader
->num_loads());
725 custom_loader
->set_context(nullptr);
727 EXPECT_TRUE(HasFactoryForURL(GURL("mojo:foo2")));
728 EXPECT_FALSE(HasFactoryForURL(GURL("mojo:foo")));
731 TEST_F(ApplicationManagerTest
, TestQueryWithLoaders
) {
732 TestApplicationLoader
* url_loader
= new TestApplicationLoader
;
733 TestApplicationLoader
* scheme_loader
= new TestApplicationLoader
;
734 application_manager_
->SetLoaderForURL(
735 scoped_ptr
<ApplicationLoader
>(url_loader
), GURL("test:test1"));
736 application_manager_
->SetLoaderForScheme(
737 scoped_ptr
<ApplicationLoader
>(scheme_loader
), "test");
739 // test::test1 should go to url_loader.
740 TestServicePtr test_service
;
741 application_manager_
->ConnectToService(GURL("test:test1?foo=bar"),
743 EXPECT_EQ(1, url_loader
->num_loads());
744 EXPECT_EQ(0, scheme_loader
->num_loads());
746 // test::test2 should go to scheme loader.
747 application_manager_
->ConnectToService(GURL("test:test2?foo=bar"),
749 EXPECT_EQ(1, url_loader
->num_loads());
750 EXPECT_EQ(1, scheme_loader
->num_loads());
753 TEST_F(ApplicationManagerTest
, TestEndApplicationClosure
) {
754 ClosingApplicationLoader
* loader
= new ClosingApplicationLoader();
755 application_manager_
->SetLoaderForScheme(
756 scoped_ptr
<ApplicationLoader
>(loader
), "test");
759 mojo::URLRequestPtr
request(mojo::URLRequest::New());
760 request
->url
= mojo::String::From("test:test");
761 application_manager_
->ConnectToApplication(
762 request
.Pass(), std::string(), GURL(), nullptr, nullptr,
763 base::Bind(&QuitClosure
, base::Unretained(&called
)));
768 TEST(ApplicationManagerTest2
, ContentHandlerConnectionGetsRequestorURL
) {
769 const GURL
content_handler_url("http://test.content.handler");
770 const GURL
requestor_url("http://requestor.url");
771 TestContext test_context
;
772 base::MessageLoop loop
;
773 TestDelegate test_delegate
;
774 test_delegate
.set_create_test_fetcher(true);
775 ApplicationManager
application_manager(&test_delegate
);
776 application_manager
.set_default_loader(nullptr);
777 application_manager
.RegisterContentHandler(kTestMimeType
,
778 content_handler_url
);
780 TestApplicationLoader
* loader
= new TestApplicationLoader
;
781 loader
->set_context(&test_context
);
782 application_manager
.SetLoaderForURL(scoped_ptr
<ApplicationLoader
>(loader
),
783 content_handler_url
);
786 mojo::URLRequestPtr
request(mojo::URLRequest::New());
787 request
->url
= mojo::String::From("test:test");
788 application_manager
.ConnectToApplication(
789 request
.Pass(), std::string(), requestor_url
, nullptr, nullptr,
790 base::Bind(&QuitClosure
, base::Unretained(&called
)));
794 ASSERT_EQ(1, loader
->num_loads());
795 EXPECT_EQ(requestor_url
, loader
->last_requestor_url());