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/public/cpp/application/application_connection.h"
11 #include "mojo/public/cpp/application/application_delegate.h"
12 #include "mojo/public/cpp/application/application_impl.h"
13 #include "mojo/public/cpp/application/interface_factory.h"
14 #include "mojo/public/cpp/bindings/strong_binding.h"
15 #include "mojo/public/interfaces/application/service_provider.mojom.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 URLResponsePtr
AsURLResponse(base::TaskRunner
* task_runner
,
44 uint32_t skip
) override
{
45 return URLResponse::New().Pass();
48 base::TaskRunner
* task_runner
,
49 base::Callback
<void(const base::FilePath
&, bool)> callback
) override
{}
50 std::string
MimeType() override
{ return kTestMimeType
; }
51 bool HasMojoMagic() override
{ return false; }
52 bool PeekFirstLine(std::string
* line
) override
{ return false; }
57 DISALLOW_COPY_AND_ASSIGN(TestMimeTypeFetcher
);
61 TestContext() : num_impls(0), num_loader_deletes(0) {}
62 std::string last_test_string
;
64 int num_loader_deletes
;
67 void QuitClosure(bool* value
) {
69 base::MessageLoop::current()->QuitWhenIdle();
72 class QuitMessageLoopErrorHandler
: public ErrorHandler
{
74 QuitMessageLoopErrorHandler() {}
75 ~QuitMessageLoopErrorHandler() override
{}
77 // |ErrorHandler| implementation:
78 void OnConnectionError() override
{
79 base::MessageLoop::current()->QuitWhenIdle();
83 DISALLOW_COPY_AND_ASSIGN(QuitMessageLoopErrorHandler
);
86 class TestServiceImpl
: public TestService
{
88 TestServiceImpl(TestContext
* context
, InterfaceRequest
<TestService
> request
)
89 : context_(context
), binding_(this, request
.Pass()) {
90 ++context_
->num_impls
;
93 ~TestServiceImpl() override
{
94 --context_
->num_impls
;
95 if (!base::MessageLoop::current()->is_running())
97 base::MessageLoop::current()->Quit();
100 // TestService implementation:
101 void Test(const String
& test_string
,
102 const Callback
<void()>& callback
) override
{
103 context_
->last_test_string
= test_string
;
108 TestContext
* context_
;
109 StrongBinding
<TestService
> binding_
;
114 explicit TestClient(TestServicePtr service
)
115 : service_(service
.Pass()), quit_after_ack_(false) {}
119 base::MessageLoop::current()->Quit();
122 void Test(const std::string
& test_string
) {
123 quit_after_ack_
= true;
124 service_
->Test(test_string
,
125 base::Bind(&TestClient::AckTest
, base::Unretained(this)));
129 TestServicePtr service_
;
130 bool quit_after_ack_
;
131 DISALLOW_COPY_AND_ASSIGN(TestClient
);
134 class TestApplicationLoader
: public ApplicationLoader
,
135 public ApplicationDelegate
,
136 public InterfaceFactory
<TestService
> {
138 TestApplicationLoader() : context_(nullptr), num_loads_(0) {}
140 ~TestApplicationLoader() override
{
142 ++context_
->num_loader_deletes
;
146 void set_context(TestContext
* context
) { context_
= context
; }
147 int num_loads() const { return num_loads_
; }
148 const std::vector
<std::string
>& GetArgs() const { return test_app_
->args(); }
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 app_impl
->ConnectToApplication(kTestBURLString
)->ConnectToService(&b_
);
292 ~TestAImpl() override
{
293 test_context_
->IncrementNumADeletes();
294 if (base::MessageLoop::current()->is_running())
299 void CallB() override
{
300 b_
->B(base::Bind(&TestAImpl::Quit
, base::Unretained(this)));
303 void CallCFromB() override
{
304 b_
->CallC(base::Bind(&TestAImpl::Quit
, base::Unretained(this)));
308 base::MessageLoop::current()->Quit();
309 test_context_
->set_a_called_quit();
310 test_context_
->QuitSoon();
313 TesterContext
* test_context_
;
315 StrongBinding
<TestA
> binding_
;
318 class TestBImpl
: public TestB
{
320 TestBImpl(ApplicationConnection
* connection
,
321 TesterContext
* test_context
,
322 InterfaceRequest
<TestB
> request
)
323 : test_context_(test_context
), binding_(this, request
.Pass()) {
324 connection
->ConnectToService(&c_
);
327 ~TestBImpl() override
{
328 test_context_
->IncrementNumBDeletes();
329 if (base::MessageLoop::current()->is_running())
330 base::MessageLoop::current()->Quit();
331 test_context_
->QuitSoon();
335 void B(const Callback
<void()>& callback
) override
{
336 test_context_
->IncrementNumBCalls();
340 void CallC(const Callback
<void()>& callback
) override
{
341 test_context_
->IncrementNumBCalls();
345 TesterContext
* test_context_
;
347 StrongBinding
<TestB
> binding_
;
350 class TestCImpl
: public TestC
{
352 TestCImpl(ApplicationConnection
* connection
,
353 TesterContext
* test_context
,
354 InterfaceRequest
<TestC
> request
)
355 : test_context_(test_context
), binding_(this, request
.Pass()) {}
357 ~TestCImpl() override
{ test_context_
->IncrementNumCDeletes(); }
360 void C(const Callback
<void()>& callback
) override
{
361 test_context_
->IncrementNumCCalls();
365 TesterContext
* test_context_
;
366 StrongBinding
<TestC
> binding_
;
369 class Tester
: public ApplicationDelegate
,
370 public ApplicationLoader
,
371 public InterfaceFactory
<TestA
>,
372 public InterfaceFactory
<TestB
>,
373 public InterfaceFactory
<TestC
> {
375 Tester(TesterContext
* context
, const std::string
& requestor_url
)
376 : context_(context
), requestor_url_(requestor_url
) {}
377 ~Tester() override
{}
380 void Load(const GURL
& url
,
381 InterfaceRequest
<Application
> application_request
) override
{
382 app_
.reset(new ApplicationImpl(this, application_request
.Pass()));
385 bool ConfigureIncomingConnection(ApplicationConnection
* connection
) override
{
386 if (!requestor_url_
.empty() &&
387 requestor_url_
!= connection
->GetRemoteApplicationURL()) {
388 context_
->set_tester_called_quit();
389 context_
->QuitSoon();
390 base::MessageLoop::current()->Quit();
393 // If we're coming from A, then add B, otherwise A.
394 if (connection
->GetRemoteApplicationURL() == kTestAURLString
)
395 connection
->AddService
<TestB
>(this);
397 connection
->AddService
<TestA
>(this);
401 bool ConfigureOutgoingConnection(ApplicationConnection
* connection
) override
{
402 // If we're connecting to B, then add C.
403 if (connection
->GetRemoteApplicationURL() == kTestBURLString
)
404 connection
->AddService
<TestC
>(this);
408 void Create(ApplicationConnection
* connection
,
409 InterfaceRequest
<TestA
> request
) override
{
410 a_bindings_
.push_back(new TestAImpl(app_
.get(), context_
, request
.Pass()));
413 void Create(ApplicationConnection
* connection
,
414 InterfaceRequest
<TestB
> request
) override
{
415 new TestBImpl(connection
, context_
, request
.Pass());
418 void Create(ApplicationConnection
* connection
,
419 InterfaceRequest
<TestC
> request
) override
{
420 new TestCImpl(connection
, context_
, request
.Pass());
423 TesterContext
* context_
;
424 scoped_ptr
<ApplicationImpl
> app_
;
425 std::string requestor_url_
;
426 ScopedVector
<TestAImpl
> a_bindings_
;
429 class TestDelegate
: public ApplicationManager::Delegate
{
431 TestDelegate() : create_test_fetcher_(false) {}
432 ~TestDelegate() override
{}
434 void AddMapping(const GURL
& from
, const GURL
& to
) { mappings_
[from
] = to
; }
436 void set_create_test_fetcher(bool create_test_fetcher
) {
437 create_test_fetcher_
= create_test_fetcher
;
440 // ApplicationManager::Delegate
441 GURL
ResolveMappings(const GURL
& url
) override
{
442 auto it
= mappings_
.find(url
);
443 if (it
!= mappings_
.end())
447 GURL
ResolveMojoURL(const GURL
& url
) override
{
448 GURL mapped_url
= ResolveMappings(url
);
449 // The shell automatically map mojo URLs.
450 if (mapped_url
.scheme() == "mojo") {
451 url::Replacements
<char> replacements
;
452 replacements
.SetScheme("file", url::Component(0, 4));
453 mapped_url
= mapped_url
.ReplaceComponents(replacements
);
457 bool CreateFetcher(const GURL
& url
,
458 const Fetcher::FetchCallback
& loader_callback
) override
{
459 if (!create_test_fetcher_
)
461 new TestMimeTypeFetcher(loader_callback
);
466 std::map
<GURL
, GURL
> mappings_
;
467 bool create_test_fetcher_
;
469 DISALLOW_COPY_AND_ASSIGN(TestDelegate
);
472 class ApplicationManagerTest
: public testing::Test
{
474 ApplicationManagerTest() : tester_context_(&loop_
) {}
476 ~ApplicationManagerTest() override
{}
478 void SetUp() override
{
479 application_manager_
.reset(new ApplicationManager(&test_delegate_
));
480 test_loader_
= new TestApplicationLoader
;
481 test_loader_
->set_context(&context_
);
482 application_manager_
->set_default_loader(
483 scoped_ptr
<ApplicationLoader
>(test_loader_
));
485 TestServicePtr service_proxy
;
486 application_manager_
->ConnectToService(GURL(kTestURLString
),
488 test_client_
.reset(new TestClient(service_proxy
.Pass()));
491 void TearDown() override
{
492 test_client_
.reset();
493 application_manager_
.reset();
496 void AddLoaderForURL(const GURL
& url
, const std::string
& requestor_url
) {
497 application_manager_
->SetLoaderForURL(
498 make_scoped_ptr(new Tester(&tester_context_
, requestor_url
)), url
);
501 bool HasFactoryForURL(const GURL
& url
) {
502 ApplicationManager::TestAPI
manager_test_api(application_manager_
.get());
503 return manager_test_api
.HasFactoryForURL(url
);
507 base::ShadowingAtExitManager at_exit_
;
508 TestDelegate test_delegate_
;
509 TestApplicationLoader
* test_loader_
;
510 TesterContext tester_context_
;
511 TestContext context_
;
512 base::MessageLoop loop_
;
513 scoped_ptr
<TestClient
> test_client_
;
514 scoped_ptr
<ApplicationManager
> application_manager_
;
515 DISALLOW_COPY_AND_ASSIGN(ApplicationManagerTest
);
518 TEST_F(ApplicationManagerTest
, Basic
) {
519 test_client_
->Test("test");
521 EXPECT_EQ(std::string("test"), context_
.last_test_string
);
524 // Confirm that no arguments are sent to an application by default.
525 TEST_F(ApplicationManagerTest
, NoArgs
) {
526 ApplicationManager
am(&test_delegate_
);
527 GURL
test_url("test:test");
528 TestApplicationLoader
* loader
= new TestApplicationLoader
;
529 loader
->set_context(&context_
);
530 am
.SetLoaderForURL(scoped_ptr
<ApplicationLoader
>(loader
), test_url
);
531 TestServicePtr test_service
;
532 am
.ConnectToService(test_url
, &test_service
);
533 TestClient
test_client(test_service
.Pass());
534 test_client
.Test("test");
536 std::vector
<std::string
> app_args
= loader
->GetArgs();
537 EXPECT_EQ(0U, app_args
.size());
540 // Confirm that url mappings are respected.
541 TEST_F(ApplicationManagerTest
, URLMapping
) {
542 ApplicationManager
am(&test_delegate_
);
543 GURL
test_url("test:test");
544 GURL
test_url2("test:test2");
545 test_delegate_
.AddMapping(test_url
, test_url2
);
546 TestApplicationLoader
* loader
= new TestApplicationLoader
;
547 loader
->set_context(&context_
);
548 am
.SetLoaderForURL(scoped_ptr
<ApplicationLoader
>(loader
), test_url2
);
550 // Connext to the mapped url
551 TestServicePtr test_service
;
552 am
.ConnectToService(test_url
, &test_service
);
553 TestClient
test_client(test_service
.Pass());
554 test_client
.Test("test");
558 // Connext to the target url
559 TestServicePtr test_service
;
560 am
.ConnectToService(test_url2
, &test_service
);
561 TestClient
test_client(test_service
.Pass());
562 test_client
.Test("test");
567 TEST_F(ApplicationManagerTest
, ClientError
) {
568 test_client_
->Test("test");
569 EXPECT_TRUE(HasFactoryForURL(GURL(kTestURLString
)));
571 EXPECT_EQ(1, context_
.num_impls
);
572 test_client_
.reset();
574 EXPECT_EQ(0, context_
.num_impls
);
575 EXPECT_TRUE(HasFactoryForURL(GURL(kTestURLString
)));
578 TEST_F(ApplicationManagerTest
, Deletes
) {
580 ApplicationManager
am(&test_delegate_
);
581 TestApplicationLoader
* default_loader
= new TestApplicationLoader
;
582 default_loader
->set_context(&context_
);
583 TestApplicationLoader
* url_loader1
= new TestApplicationLoader
;
584 TestApplicationLoader
* url_loader2
= new TestApplicationLoader
;
585 url_loader1
->set_context(&context_
);
586 url_loader2
->set_context(&context_
);
587 TestApplicationLoader
* scheme_loader1
= new TestApplicationLoader
;
588 TestApplicationLoader
* scheme_loader2
= new TestApplicationLoader
;
589 scheme_loader1
->set_context(&context_
);
590 scheme_loader2
->set_context(&context_
);
591 am
.set_default_loader(scoped_ptr
<ApplicationLoader
>(default_loader
));
592 am
.SetLoaderForURL(scoped_ptr
<ApplicationLoader
>(url_loader1
),
594 am
.SetLoaderForURL(scoped_ptr
<ApplicationLoader
>(url_loader2
),
596 am
.SetLoaderForScheme(scoped_ptr
<ApplicationLoader
>(scheme_loader1
),
598 am
.SetLoaderForScheme(scoped_ptr
<ApplicationLoader
>(scheme_loader2
),
601 EXPECT_EQ(5, context_
.num_loader_deletes
);
604 // Confirm that both urls and schemes can have their loaders explicitly set.
605 TEST_F(ApplicationManagerTest
, SetLoaders
) {
606 TestApplicationLoader
* default_loader
= new TestApplicationLoader
;
607 TestApplicationLoader
* url_loader
= new TestApplicationLoader
;
608 TestApplicationLoader
* scheme_loader
= new TestApplicationLoader
;
609 application_manager_
->set_default_loader(
610 scoped_ptr
<ApplicationLoader
>(default_loader
));
611 application_manager_
->SetLoaderForURL(
612 scoped_ptr
<ApplicationLoader
>(url_loader
), GURL("test:test1"));
613 application_manager_
->SetLoaderForScheme(
614 scoped_ptr
<ApplicationLoader
>(scheme_loader
), "test");
616 // test::test1 should go to url_loader.
617 TestServicePtr test_service
;
618 application_manager_
->ConnectToService(GURL("test:test1"), &test_service
);
619 EXPECT_EQ(1, url_loader
->num_loads());
620 EXPECT_EQ(0, scheme_loader
->num_loads());
621 EXPECT_EQ(0, default_loader
->num_loads());
623 // test::test2 should go to scheme loader.
624 application_manager_
->ConnectToService(GURL("test:test2"), &test_service
);
625 EXPECT_EQ(1, url_loader
->num_loads());
626 EXPECT_EQ(1, scheme_loader
->num_loads());
627 EXPECT_EQ(0, default_loader
->num_loads());
629 // http::test1 should go to default loader.
630 application_manager_
->ConnectToService(GURL("http:test1"), &test_service
);
631 EXPECT_EQ(1, url_loader
->num_loads());
632 EXPECT_EQ(1, scheme_loader
->num_loads());
633 EXPECT_EQ(1, default_loader
->num_loads());
636 // Confirm that the url of a service is correctly passed to another service that
638 TEST_F(ApplicationManagerTest
, ACallB
) {
639 // Any url can load a.
640 AddLoaderForURL(GURL(kTestAURLString
), std::string());
642 // Only a can load b.
643 AddLoaderForURL(GURL(kTestBURLString
), kTestAURLString
);
646 application_manager_
->ConnectToService(GURL(kTestAURLString
), &a
);
649 EXPECT_EQ(1, tester_context_
.num_b_calls());
650 EXPECT_TRUE(tester_context_
.a_called_quit());
653 // A calls B which calls C.
654 TEST_F(ApplicationManagerTest
, BCallC
) {
655 // Any url can load a.
656 AddLoaderForURL(GURL(kTestAURLString
), std::string());
658 // Only a can load b.
659 AddLoaderForURL(GURL(kTestBURLString
), kTestAURLString
);
662 application_manager_
->ConnectToService(GURL(kTestAURLString
), &a
);
666 EXPECT_EQ(1, tester_context_
.num_b_calls());
667 EXPECT_EQ(1, tester_context_
.num_c_calls());
668 EXPECT_TRUE(tester_context_
.a_called_quit());
671 // Confirm that a service impl will be deleted if the app that connected to
673 TEST_F(ApplicationManagerTest
, BDeleted
) {
674 AddLoaderForURL(GURL(kTestAURLString
), std::string());
675 AddLoaderForURL(GURL(kTestBURLString
), std::string());
678 application_manager_
->ConnectToService(GURL(kTestAURLString
), &a
);
684 application_manager_
->SetLoaderForURL(scoped_ptr
<ApplicationLoader
>(),
685 GURL(kTestAURLString
));
688 EXPECT_EQ(1, tester_context_
.num_b_deletes());
691 // Confirm that the url of a service is correctly passed to another service that
692 // it loads, and that it can be rejected.
693 TEST_F(ApplicationManagerTest
, ANoLoadB
) {
694 // Any url can load a.
695 AddLoaderForURL(GURL(kTestAURLString
), std::string());
697 // Only c can load b, so this will fail.
698 AddLoaderForURL(GURL(kTestBURLString
), "test:TestC");
701 application_manager_
->ConnectToService(GURL(kTestAURLString
), &a
);
704 EXPECT_EQ(0, tester_context_
.num_b_calls());
706 EXPECT_FALSE(tester_context_
.a_called_quit());
707 EXPECT_TRUE(tester_context_
.tester_called_quit());
710 TEST_F(ApplicationManagerTest
, NoServiceNoLoad
) {
711 AddLoaderForURL(GURL(kTestAURLString
), std::string());
713 // There is no TestC service implementation registered with
714 // ApplicationManager, so this cannot succeed (but also shouldn't crash).
716 application_manager_
->ConnectToService(GURL(kTestAURLString
), &c
);
717 QuitMessageLoopErrorHandler quitter
;
718 c
.set_error_handler(&quitter
);
721 EXPECT_TRUE(c
.encountered_error());
724 TEST_F(ApplicationManagerTest
, MappedURLsShouldNotCauseDuplicateLoad
) {
725 test_delegate_
.AddMapping(GURL("foo:foo2"), GURL("foo:foo"));
726 // 1 because ApplicationManagerTest connects once at startup.
727 EXPECT_EQ(1, test_loader_
->num_loads());
729 TestServicePtr test_service
;
730 application_manager_
->ConnectToService(GURL("foo:foo"), &test_service
);
731 EXPECT_EQ(2, test_loader_
->num_loads());
733 TestServicePtr test_service2
;
734 application_manager_
->ConnectToService(GURL("foo:foo2"), &test_service2
);
735 EXPECT_EQ(2, test_loader_
->num_loads());
737 TestServicePtr test_service3
;
738 application_manager_
->ConnectToService(GURL("bar:bar"), &test_service2
);
739 EXPECT_EQ(3, test_loader_
->num_loads());
742 TEST_F(ApplicationManagerTest
, MappedURLsShouldWorkWithLoaders
) {
743 TestApplicationLoader
* custom_loader
= new TestApplicationLoader
;
745 custom_loader
->set_context(&context
);
746 application_manager_
->SetLoaderForURL(make_scoped_ptr(custom_loader
),
748 test_delegate_
.AddMapping(GURL("mojo:foo2"), GURL("mojo:foo"));
750 TestServicePtr test_service
;
751 application_manager_
->ConnectToService(GURL("mojo:foo2"), &test_service
);
752 EXPECT_EQ(1, custom_loader
->num_loads());
753 custom_loader
->set_context(nullptr);
755 EXPECT_TRUE(HasFactoryForURL(GURL("mojo:foo2")));
756 EXPECT_FALSE(HasFactoryForURL(GURL("mojo:foo")));
759 TEST_F(ApplicationManagerTest
, TestQueryWithLoaders
) {
760 TestApplicationLoader
* url_loader
= new TestApplicationLoader
;
761 TestApplicationLoader
* scheme_loader
= new TestApplicationLoader
;
762 application_manager_
->SetLoaderForURL(
763 scoped_ptr
<ApplicationLoader
>(url_loader
), GURL("test:test1"));
764 application_manager_
->SetLoaderForScheme(
765 scoped_ptr
<ApplicationLoader
>(scheme_loader
), "test");
767 // test::test1 should go to url_loader.
768 TestServicePtr test_service
;
769 application_manager_
->ConnectToService(GURL("test:test1?foo=bar"),
771 EXPECT_EQ(1, url_loader
->num_loads());
772 EXPECT_EQ(0, scheme_loader
->num_loads());
774 // test::test2 should go to scheme loader.
775 application_manager_
->ConnectToService(GURL("test:test2?foo=bar"),
777 EXPECT_EQ(1, url_loader
->num_loads());
778 EXPECT_EQ(1, scheme_loader
->num_loads());
781 TEST_F(ApplicationManagerTest
, TestEndApplicationClosure
) {
782 ClosingApplicationLoader
* loader
= new ClosingApplicationLoader();
783 application_manager_
->SetLoaderForScheme(
784 scoped_ptr
<ApplicationLoader
>(loader
), "test");
787 application_manager_
->ConnectToApplication(
788 GURL("test:test"), GURL(), nullptr, nullptr,
789 base::Bind(&QuitClosure
, base::Unretained(&called
)));
794 TEST(ApplicationManagerTest2
, ContentHandlerConnectionGetsRequestorURL
) {
795 const GURL
content_handler_url("http://test.content.handler");
796 const GURL
requestor_url("http://requestor.url");
797 TestContext test_context
;
798 base::MessageLoop loop
;
799 TestDelegate test_delegate
;
800 test_delegate
.set_create_test_fetcher(true);
801 ApplicationManager
application_manager(&test_delegate
);
802 application_manager
.set_default_loader(nullptr);
803 application_manager
.RegisterContentHandler(kTestMimeType
,
804 content_handler_url
);
806 TestApplicationLoader
* loader
= new TestApplicationLoader
;
807 loader
->set_context(&test_context
);
808 application_manager
.SetLoaderForURL(scoped_ptr
<ApplicationLoader
>(loader
),
809 content_handler_url
);
812 application_manager
.ConnectToApplication(
813 GURL("test:test"), requestor_url
, nullptr, nullptr,
814 base::Bind(&QuitClosure
, base::Unretained(&called
)));
818 ASSERT_EQ(1, loader
->num_loads());
819 EXPECT_EQ(requestor_url
, loader
->last_requestor_url());