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 "base/run_loop.h"
11 #include "mojo/application/public/cpp/application_connection.h"
12 #include "mojo/application/public/cpp/application_delegate.h"
13 #include "mojo/application/public/cpp/application_impl.h"
14 #include "mojo/application/public/cpp/interface_factory.h"
15 #include "mojo/application/public/interfaces/content_handler.mojom.h"
16 #include "mojo/application/public/interfaces/service_provider.mojom.h"
17 #include "mojo/public/cpp/bindings/strong_binding.h"
18 #include "mojo/shell/application_fetcher.h"
19 #include "mojo/shell/application_loader.h"
20 #include "mojo/shell/application_manager.h"
21 #include "mojo/shell/fetcher.h"
22 #include "mojo/shell/test.mojom.h"
23 #include "testing/gtest/include/gtest/gtest.h"
29 const char kTestURLString
[] = "test:testService";
30 const char kTestAURLString
[] = "test:TestA";
31 const char kTestBURLString
[] = "test:TestB";
33 const char kTestMimeType
[] = "test/mime-type";
35 class TestMimeTypeFetcher
: public Fetcher
{
37 TestMimeTypeFetcher(const FetchCallback
& fetch_callback
,
39 const std::string
& mime_type
)
40 : Fetcher(fetch_callback
), url_(url
), mime_type_(mime_type
) {
41 loader_callback_
.Run(make_scoped_ptr(this));
43 ~TestMimeTypeFetcher() override
{}
46 const GURL
& GetURL() const override
{ return url_
; }
47 GURL
GetRedirectURL() const override
{ return GURL("yyy"); }
48 GURL
GetRedirectReferer() const override
{ return GURL(); }
49 URLResponsePtr
AsURLResponse(base::TaskRunner
* task_runner
,
50 uint32_t skip
) override
{
51 return URLResponse::New().Pass();
54 base::TaskRunner
* task_runner
,
55 base::Callback
<void(const base::FilePath
&, bool)> callback
) override
{}
56 std::string
MimeType() override
{ return mime_type_
; }
57 bool HasMojoMagic() override
{ return false; }
58 bool PeekFirstLine(std::string
* line
) override
{ return false; }
62 const std::string mime_type_
;
64 DISALLOW_COPY_AND_ASSIGN(TestMimeTypeFetcher
);
68 TestContext() : num_impls(0), num_loader_deletes(0) {}
69 std::string last_test_string
;
71 int num_loader_deletes
;
74 void QuitClosure(bool* value
) {
76 base::MessageLoop::current()->QuitWhenIdle();
79 class TestServiceImpl
: public TestService
{
81 TestServiceImpl(TestContext
* context
, InterfaceRequest
<TestService
> request
)
82 : context_(context
), binding_(this, request
.Pass()) {
83 ++context_
->num_impls
;
86 ~TestServiceImpl() override
{
87 --context_
->num_impls
;
88 if (!base::MessageLoop::current()->is_running())
90 base::MessageLoop::current()->Quit();
93 // TestService implementation:
94 void Test(const String
& test_string
,
95 const Callback
<void()>& callback
) override
{
96 context_
->last_test_string
= test_string
;
101 TestContext
* context_
;
102 StrongBinding
<TestService
> binding_
;
107 explicit TestClient(TestServicePtr service
)
108 : service_(service
.Pass()), quit_after_ack_(false) {}
112 base::MessageLoop::current()->Quit();
115 void Test(const std::string
& test_string
) {
116 quit_after_ack_
= true;
117 service_
->Test(test_string
,
118 base::Bind(&TestClient::AckTest
, base::Unretained(this)));
122 TestServicePtr service_
;
123 bool quit_after_ack_
;
124 DISALLOW_COPY_AND_ASSIGN(TestClient
);
127 class TestContentHandler
: public ContentHandler
, public ApplicationDelegate
{
129 TestContentHandler(ApplicationConnection
* connection
,
130 InterfaceRequest
<ContentHandler
> request
)
131 : binding_(this, request
.Pass()) {}
134 void StartApplication(InterfaceRequest
<Application
> application_request
,
135 URLResponsePtr response
) override
{
136 apps_
.push_back(new ApplicationImpl(this, application_request
.Pass()));
140 StrongBinding
<ContentHandler
> binding_
;
141 ScopedVector
<ApplicationImpl
> apps_
;
143 DISALLOW_COPY_AND_ASSIGN(TestContentHandler
);
146 class TestApplicationLoader
: public ApplicationLoader
,
147 public ApplicationDelegate
,
148 public InterfaceFactory
<TestService
>,
149 public InterfaceFactory
<ContentHandler
> {
151 TestApplicationLoader()
152 : context_(nullptr), num_loads_(0), create_content_handler_(false) {}
154 ~TestApplicationLoader() override
{
156 ++context_
->num_loader_deletes
;
160 void set_create_content_handler(bool value
) {
161 create_content_handler_
= true;
164 void set_context(TestContext
* context
) { context_
= context
; }
165 int num_loads() const { return num_loads_
; }
166 const GURL
& last_requestor_url() const { return last_requestor_url_
; }
169 // ApplicationLoader implementation.
170 void Load(const GURL
& url
,
171 InterfaceRequest
<Application
> application_request
) override
{
173 test_app_
.reset(new ApplicationImpl(this, application_request
.Pass()));
176 // ApplicationDelegate implementation.
177 bool ConfigureIncomingConnection(ApplicationConnection
* connection
) override
{
178 connection
->AddService
<TestService
>(this);
179 if (create_content_handler_
)
180 connection
->AddService
<ContentHandler
>(this);
181 last_requestor_url_
= GURL(connection
->GetRemoteApplicationURL());
185 // InterfaceFactory<TestService> implementation.
186 void Create(ApplicationConnection
* connection
,
187 InterfaceRequest
<TestService
> request
) override
{
188 new TestServiceImpl(context_
, request
.Pass());
191 // InterfaceFactory<ContentHandler> implementation.
192 void Create(ApplicationConnection
* connection
,
193 InterfaceRequest
<ContentHandler
> request
) override
{
194 new TestContentHandler(connection
, request
.Pass());
197 scoped_ptr
<ApplicationImpl
> test_app_
;
198 TestContext
* context_
;
200 GURL last_requestor_url_
;
201 bool create_content_handler_
;
203 DISALLOW_COPY_AND_ASSIGN(TestApplicationLoader
);
206 class ClosingApplicationLoader
: public ApplicationLoader
{
208 // ApplicationLoader implementation.
209 void Load(const GURL
& url
,
210 InterfaceRequest
<Application
> application_request
) override
{}
213 class TesterContext
{
215 explicit TesterContext(base::MessageLoop
* loop
)
221 tester_called_quit_(false),
222 a_called_quit_(false),
225 void IncrementNumBCalls() {
226 base::AutoLock
lock(lock_
);
230 void IncrementNumCCalls() {
231 base::AutoLock
lock(lock_
);
235 void IncrementNumADeletes() {
236 base::AutoLock
lock(lock_
);
240 void IncrementNumBDeletes() {
241 base::AutoLock
lock(lock_
);
245 void IncrementNumCDeletes() {
246 base::AutoLock
lock(lock_
);
250 void set_tester_called_quit() {
251 base::AutoLock
lock(lock_
);
252 tester_called_quit_
= true;
255 void set_a_called_quit() {
256 base::AutoLock
lock(lock_
);
257 a_called_quit_
= true;
261 base::AutoLock
lock(lock_
);
265 base::AutoLock
lock(lock_
);
268 int num_a_deletes() {
269 base::AutoLock
lock(lock_
);
270 return num_a_deletes_
;
272 int num_b_deletes() {
273 base::AutoLock
lock(lock_
);
274 return num_b_deletes_
;
276 int num_c_deletes() {
277 base::AutoLock
lock(lock_
);
278 return num_c_deletes_
;
280 bool tester_called_quit() {
281 base::AutoLock
lock(lock_
);
282 return tester_called_quit_
;
284 bool a_called_quit() {
285 base::AutoLock
lock(lock_
);
286 return a_called_quit_
;
290 loop_
->PostTask(FROM_HERE
, base::MessageLoop::QuitWhenIdleClosure());
294 // lock_ protects all members except for loop_ which must be unchanged for the
295 // lifetime of this class.
302 bool tester_called_quit_
;
305 base::MessageLoop
* loop_
;
308 // Used to test that the requestor url will be correctly passed.
309 class TestAImpl
: public TestA
{
311 TestAImpl(ApplicationImpl
* app_impl
,
312 TesterContext
* test_context
,
313 InterfaceRequest
<TestA
> request
)
314 : test_context_(test_context
), binding_(this, request
.Pass()) {
315 mojo::URLRequestPtr
request2(mojo::URLRequest::New());
316 request2
->url
= mojo::String::From(kTestBURLString
);
317 connection_
= app_impl
->ConnectToApplication(request2
.Pass());
318 connection_
->ConnectToService(&b_
);
321 ~TestAImpl() override
{
322 test_context_
->IncrementNumADeletes();
323 if (base::MessageLoop::current()->is_running())
328 void CallB() override
{
329 b_
->B(base::Bind(&TestAImpl::Quit
, base::Unretained(this)));
332 void CallCFromB() override
{
333 b_
->CallC(base::Bind(&TestAImpl::Quit
, base::Unretained(this)));
337 base::MessageLoop::current()->Quit();
338 test_context_
->set_a_called_quit();
339 test_context_
->QuitSoon();
342 scoped_ptr
<ApplicationConnection
> connection_
;
343 TesterContext
* test_context_
;
345 StrongBinding
<TestA
> binding_
;
348 class TestBImpl
: public TestB
{
350 TestBImpl(ApplicationConnection
* connection
,
351 TesterContext
* test_context
,
352 InterfaceRequest
<TestB
> request
)
353 : test_context_(test_context
), binding_(this, request
.Pass()) {
354 connection
->ConnectToService(&c_
);
357 ~TestBImpl() override
{
358 test_context_
->IncrementNumBDeletes();
359 if (base::MessageLoop::current()->is_running())
360 base::MessageLoop::current()->Quit();
361 test_context_
->QuitSoon();
365 void B(const Callback
<void()>& callback
) override
{
366 test_context_
->IncrementNumBCalls();
370 void CallC(const Callback
<void()>& callback
) override
{
371 test_context_
->IncrementNumBCalls();
375 TesterContext
* test_context_
;
377 StrongBinding
<TestB
> binding_
;
380 class TestCImpl
: public TestC
{
382 TestCImpl(ApplicationConnection
* connection
,
383 TesterContext
* test_context
,
384 InterfaceRequest
<TestC
> request
)
385 : test_context_(test_context
), binding_(this, request
.Pass()) {}
387 ~TestCImpl() override
{ test_context_
->IncrementNumCDeletes(); }
390 void C(const Callback
<void()>& callback
) override
{
391 test_context_
->IncrementNumCCalls();
395 TesterContext
* test_context_
;
396 StrongBinding
<TestC
> binding_
;
399 class Tester
: public ApplicationDelegate
,
400 public ApplicationLoader
,
401 public InterfaceFactory
<TestA
>,
402 public InterfaceFactory
<TestB
>,
403 public InterfaceFactory
<TestC
> {
405 Tester(TesterContext
* context
, const std::string
& requestor_url
)
406 : context_(context
), requestor_url_(requestor_url
) {}
407 ~Tester() override
{}
410 void Load(const GURL
& url
,
411 InterfaceRequest
<Application
> application_request
) override
{
412 app_
.reset(new ApplicationImpl(this, application_request
.Pass()));
415 bool ConfigureIncomingConnection(ApplicationConnection
* connection
) override
{
416 if (!requestor_url_
.empty() &&
417 requestor_url_
!= connection
->GetRemoteApplicationURL()) {
418 context_
->set_tester_called_quit();
419 context_
->QuitSoon();
420 base::MessageLoop::current()->Quit();
423 // If we're coming from A, then add B, otherwise A.
424 if (connection
->GetRemoteApplicationURL() == kTestAURLString
)
425 connection
->AddService
<TestB
>(this);
427 connection
->AddService
<TestA
>(this);
431 bool ConfigureOutgoingConnection(ApplicationConnection
* connection
) override
{
432 // If we're connecting to B, then add C.
433 if (connection
->GetRemoteApplicationURL() == kTestBURLString
)
434 connection
->AddService
<TestC
>(this);
438 void Create(ApplicationConnection
* connection
,
439 InterfaceRequest
<TestA
> request
) override
{
440 a_bindings_
.push_back(new TestAImpl(app_
.get(), context_
, request
.Pass()));
443 void Create(ApplicationConnection
* connection
,
444 InterfaceRequest
<TestB
> request
) override
{
445 new TestBImpl(connection
, context_
, request
.Pass());
448 void Create(ApplicationConnection
* connection
,
449 InterfaceRequest
<TestC
> request
) override
{
450 new TestCImpl(connection
, context_
, request
.Pass());
453 TesterContext
* context_
;
454 scoped_ptr
<ApplicationImpl
> app_
;
455 std::string requestor_url_
;
456 ScopedVector
<TestAImpl
> a_bindings_
;
459 class TestApplicationFetcher
: public ApplicationFetcher
{
461 TestApplicationFetcher()
462 : create_test_fetcher_(false),
464 mime_type_(kTestMimeType
) {}
465 ~TestApplicationFetcher() override
{}
467 void set_create_test_fetcher(bool create_test_fetcher
) {
468 create_test_fetcher_
= create_test_fetcher
;
471 void set_fetcher_url(const GURL
& url
) { fetcher_url_
= url
; }
473 void set_mime_type(const std::string
& mime_type
) { mime_type_
= mime_type
; }
475 // ApplicationManager::Delegate
476 void SetApplicationManager(ApplicationManager
* manager
) override
{}
477 GURL
ResolveURL(const GURL
& url
) override
{
478 GURL resolved_url
= url
;
479 // The shell automatically map mojo URLs.
480 if (resolved_url
.scheme() == "mojo") {
481 url::Replacements
<char> replacements
;
482 replacements
.SetScheme("file", url::Component(0, 4));
483 resolved_url
= resolved_url
.ReplaceComponents(replacements
);
487 void FetchRequest(URLRequestPtr request
,
488 const Fetcher::FetchCallback
& loader_callback
) override
{
489 if (create_test_fetcher_
)
490 new TestMimeTypeFetcher(loader_callback
, fetcher_url_
, mime_type_
);
494 bool create_test_fetcher_
;
496 std::string mime_type_
;
498 DISALLOW_COPY_AND_ASSIGN(TestApplicationFetcher
);
501 class ApplicationManagerTest
: public testing::Test
{
503 ApplicationManagerTest() : tester_context_(&loop_
) {}
505 ~ApplicationManagerTest() override
{}
507 void SetUp() override
{
508 application_manager_
.reset(new ApplicationManager(
509 make_scoped_ptr(new TestApplicationFetcher
)));
510 test_loader_
= new TestApplicationLoader
;
511 test_loader_
->set_context(&context_
);
512 application_manager_
->set_default_loader(
513 scoped_ptr
<ApplicationLoader
>(test_loader_
));
515 TestServicePtr service_proxy
;
516 application_manager_
->ConnectToService(GURL(kTestURLString
),
518 test_client_
.reset(new TestClient(service_proxy
.Pass()));
521 void TearDown() override
{
522 test_client_
.reset();
523 application_manager_
.reset();
526 void AddLoaderForURL(const GURL
& url
, const std::string
& requestor_url
) {
527 application_manager_
->SetLoaderForURL(
528 make_scoped_ptr(new Tester(&tester_context_
, requestor_url
)), url
);
531 bool HasRunningInstanceForURL(const GURL
& url
) {
532 ApplicationManager::TestAPI
manager_test_api(application_manager_
.get());
533 return manager_test_api
.HasRunningInstanceForURL(url
);
537 base::ShadowingAtExitManager at_exit_
;
538 TestApplicationLoader
* test_loader_
;
539 TesterContext tester_context_
;
540 TestContext context_
;
541 base::MessageLoop loop_
;
542 scoped_ptr
<TestClient
> test_client_
;
543 scoped_ptr
<ApplicationManager
> application_manager_
;
544 DISALLOW_COPY_AND_ASSIGN(ApplicationManagerTest
);
547 TEST_F(ApplicationManagerTest
, Basic
) {
548 test_client_
->Test("test");
550 EXPECT_EQ(std::string("test"), context_
.last_test_string
);
553 TEST_F(ApplicationManagerTest
, ClientError
) {
554 test_client_
->Test("test");
555 EXPECT_TRUE(HasRunningInstanceForURL(GURL(kTestURLString
)));
557 EXPECT_EQ(1, context_
.num_impls
);
558 test_client_
.reset();
560 EXPECT_EQ(0, context_
.num_impls
);
561 EXPECT_TRUE(HasRunningInstanceForURL(GURL(kTestURLString
)));
564 TEST_F(ApplicationManagerTest
, Deletes
) {
566 ApplicationManager
am(make_scoped_ptr(new TestApplicationFetcher
));
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 c
.set_connection_error_handler(
704 []() { base::MessageLoop::current()->QuitWhenIdle(); });
707 EXPECT_TRUE(c
.encountered_error());
710 TEST_F(ApplicationManagerTest
, TestQueryWithLoaders
) {
711 TestApplicationLoader
* url_loader
= new TestApplicationLoader
;
712 TestApplicationLoader
* scheme_loader
= new TestApplicationLoader
;
713 application_manager_
->SetLoaderForURL(
714 scoped_ptr
<ApplicationLoader
>(url_loader
), GURL("test:test1"));
715 application_manager_
->SetLoaderForScheme(
716 scoped_ptr
<ApplicationLoader
>(scheme_loader
), "test");
718 // test::test1 should go to url_loader.
719 TestServicePtr test_service
;
720 application_manager_
->ConnectToService(GURL("test:test1?foo=bar"),
722 EXPECT_EQ(1, url_loader
->num_loads());
723 EXPECT_EQ(0, scheme_loader
->num_loads());
725 // test::test2 should go to scheme loader.
726 application_manager_
->ConnectToService(GURL("test:test2?foo=bar"),
728 EXPECT_EQ(1, url_loader
->num_loads());
729 EXPECT_EQ(1, scheme_loader
->num_loads());
732 TEST_F(ApplicationManagerTest
, TestEndApplicationClosure
) {
733 ClosingApplicationLoader
* loader
= new ClosingApplicationLoader();
734 application_manager_
->SetLoaderForScheme(
735 scoped_ptr
<ApplicationLoader
>(loader
), "test");
738 scoped_ptr
<ConnectToApplicationParams
> params(new ConnectToApplicationParams
);
739 params
->SetURLInfo(GURL("test:test"));
740 params
->set_filter(GetPermissiveCapabilityFilter());
741 params
->set_on_application_end(
742 base::Bind(&QuitClosure
, base::Unretained(&called
)));
743 application_manager_
->ConnectToApplication(params
.Pass());
748 TEST(ApplicationManagerTest2
, ContentHandlerConnectionGetsRequestorURL
) {
749 const GURL
content_handler_url("http://test.content.handler");
750 const GURL
requestor_url("http://requestor.url");
751 TestContext test_context
;
752 base::MessageLoop loop
;
753 scoped_ptr
<TestApplicationFetcher
> test_application_fetcher(
754 new TestApplicationFetcher
);
755 test_application_fetcher
->set_create_test_fetcher(true);
756 ApplicationManager
application_manager(test_application_fetcher
.Pass());
757 application_manager
.set_default_loader(nullptr);
758 application_manager
.RegisterContentHandler(kTestMimeType
,
759 content_handler_url
);
761 TestApplicationLoader
* loader
= new TestApplicationLoader
;
762 loader
->set_context(&test_context
);
763 application_manager
.SetLoaderForURL(scoped_ptr
<ApplicationLoader
>(loader
),
764 content_handler_url
);
767 scoped_ptr
<ConnectToApplicationParams
> params(new ConnectToApplicationParams
);
768 params
->set_originator_identity(Identity(requestor_url
));
769 params
->set_originator_filter(GetPermissiveCapabilityFilter());
770 params
->SetURLInfo(GURL("test:test"));
771 params
->set_filter(GetPermissiveCapabilityFilter());
772 params
->set_on_application_end(
773 base::Bind(&QuitClosure
, base::Unretained(&called
)));
774 application_manager
.ConnectToApplication(params
.Pass());
778 ASSERT_EQ(1, loader
->num_loads());
779 EXPECT_EQ(requestor_url
, loader
->last_requestor_url());
782 TEST_F(ApplicationManagerTest
, SameIdentityShouldNotCauseDuplicateLoad
) {
783 // 1 because ApplicationManagerTest connects once at startup.
784 EXPECT_EQ(1, test_loader_
->num_loads());
786 TestServicePtr test_service
;
787 application_manager_
->ConnectToService(GURL("http://www.example.org/abc?def"),
789 EXPECT_EQ(2, test_loader_
->num_loads());
791 // Exactly the same URL as above.
792 application_manager_
->ConnectToService(GURL("http://www.example.org/abc?def"),
794 EXPECT_EQ(2, test_loader_
->num_loads());
796 // The same identity as the one above because only the query string is
798 application_manager_
->ConnectToService(GURL("http://www.example.org/abc"),
800 EXPECT_EQ(2, test_loader_
->num_loads());
802 // A different identity because the path is different.
803 application_manager_
->ConnectToService(
804 GURL("http://www.example.org/another_path"), &test_service
);
805 EXPECT_EQ(3, test_loader_
->num_loads());
807 // A different identity because the domain is different.
808 application_manager_
->ConnectToService(
809 GURL("http://www.another_domain.org/abc"), &test_service
);
810 EXPECT_EQ(4, test_loader_
->num_loads());
813 TEST(ApplicationManagerTest2
,
814 MultipleConnectionsToContentHandlerGetSameContentHandlerId
) {
815 base::MessageLoop loop
;
816 const GURL
content_handler_url("http://test.content.handler");
817 const GURL
requestor_url("http://requestor.url");
818 TestContext test_context
;
819 scoped_ptr
<TestApplicationFetcher
> test_application_fetcher(
820 new TestApplicationFetcher
);
821 test_application_fetcher
->set_fetcher_url(GURL("test:test"));
822 test_application_fetcher
->set_create_test_fetcher(true);
823 ApplicationManager
application_manager(test_application_fetcher
.Pass());
824 application_manager
.set_default_loader(nullptr);
825 application_manager
.RegisterContentHandler(kTestMimeType
,
826 content_handler_url
);
828 TestApplicationLoader
* content_handler_loader
= new TestApplicationLoader
;
829 content_handler_loader
->set_create_content_handler(true);
830 content_handler_loader
->set_context(&test_context
);
831 application_manager
.SetLoaderForURL(
832 scoped_ptr
<ApplicationLoader
>(content_handler_loader
),
833 content_handler_url
);
835 uint32_t content_handler_id
;
837 base::RunLoop run_loop
;
838 scoped_ptr
<ConnectToApplicationParams
> params(
839 new ConnectToApplicationParams
);
840 params
->set_originator_identity(Identity(requestor_url
));
841 params
->set_originator_filter(GetPermissiveCapabilityFilter());
842 params
->SetURLInfo(GURL("test:test"));
843 params
->set_filter(GetPermissiveCapabilityFilter());
844 params
->set_connect_callback([&content_handler_id
, &run_loop
](uint32_t t
) {
845 content_handler_id
= t
;
848 application_manager
.ConnectToApplication(params
.Pass());
850 EXPECT_NE(Shell::kInvalidContentHandlerID
, content_handler_id
);
853 uint32_t content_handler_id2
;
855 base::RunLoop run_loop
;
856 scoped_ptr
<ConnectToApplicationParams
> params(
857 new ConnectToApplicationParams
);
858 params
->set_originator_identity(Identity(requestor_url
));
859 params
->set_originator_filter(GetPermissiveCapabilityFilter());
860 params
->SetURLInfo(GURL("test:test"));
861 params
->set_filter(GetPermissiveCapabilityFilter());
862 params
->set_connect_callback([&content_handler_id2
, &run_loop
](uint32_t t
) {
863 content_handler_id2
= t
;
866 application_manager
.ConnectToApplication(params
.Pass());
868 EXPECT_NE(Shell::kInvalidContentHandlerID
, content_handler_id2
);
870 EXPECT_EQ(content_handler_id
, content_handler_id2
);
873 TEST(ApplicationManagerTest2
, DifferedContentHandlersGetDifferentIDs
) {
874 base::MessageLoop loop
;
875 const GURL
content_handler_url("http://test.content.handler");
876 const GURL
requestor_url("http://requestor.url");
877 TestContext test_context
;
878 TestApplicationFetcher
* test_application_fetcher
= new TestApplicationFetcher
;
879 test_application_fetcher
->set_fetcher_url(GURL("test:test"));
880 test_application_fetcher
->set_create_test_fetcher(true);
881 ApplicationManager
application_manager(
882 make_scoped_ptr(test_application_fetcher
));
883 application_manager
.set_default_loader(nullptr);
884 application_manager
.RegisterContentHandler(kTestMimeType
,
885 content_handler_url
);
887 TestApplicationLoader
* content_handler_loader
= new TestApplicationLoader
;
888 content_handler_loader
->set_create_content_handler(true);
889 content_handler_loader
->set_context(&test_context
);
890 application_manager
.SetLoaderForURL(
891 scoped_ptr
<ApplicationLoader
>(content_handler_loader
),
892 content_handler_url
);
894 uint32_t content_handler_id
;
896 base::RunLoop run_loop
;
897 scoped_ptr
<ConnectToApplicationParams
> params(
898 new ConnectToApplicationParams
);
899 params
->set_originator_identity(Identity(requestor_url
));
900 params
->set_originator_filter(GetPermissiveCapabilityFilter());
901 params
->SetURLInfo(GURL("test:test"));
902 params
->set_filter(GetPermissiveCapabilityFilter());
903 params
->set_connect_callback([&content_handler_id
, &run_loop
](uint32_t t
) {
904 content_handler_id
= t
;
907 application_manager
.ConnectToApplication(params
.Pass());
909 EXPECT_NE(Shell::kInvalidContentHandlerID
, content_handler_id
);
912 const std::string
mime_type2("test/mime-type2");
913 const GURL
content_handler_url2("http://test.content2.handler");
914 test_application_fetcher
->set_fetcher_url(GURL("test2:test2"));
915 test_application_fetcher
->set_mime_type(mime_type2
);
916 application_manager
.RegisterContentHandler(mime_type2
, content_handler_url2
);
918 TestApplicationLoader
* content_handler_loader2
= new TestApplicationLoader
;
919 content_handler_loader
->set_create_content_handler(true);
920 content_handler_loader
->set_context(&test_context
);
921 application_manager
.SetLoaderForURL(
922 scoped_ptr
<ApplicationLoader
>(content_handler_loader2
),
923 content_handler_url2
);
925 uint32_t content_handler_id2
;
927 base::RunLoop run_loop
;
928 scoped_ptr
<ConnectToApplicationParams
> params(
929 new ConnectToApplicationParams
);
930 params
->set_originator_identity(Identity(requestor_url
));
931 params
->set_originator_filter(GetPermissiveCapabilityFilter());
932 params
->SetURLInfo(GURL("test2:test2"));
933 params
->set_filter(GetPermissiveCapabilityFilter());
934 params
->set_connect_callback([&content_handler_id2
, &run_loop
](uint32_t t
) {
935 content_handler_id2
= t
;
938 application_manager
.ConnectToApplication(params
.Pass());
940 EXPECT_NE(Shell::kInvalidContentHandlerID
, content_handler_id2
);
942 EXPECT_NE(content_handler_id
, content_handler_id2
);
945 TEST_F(ApplicationManagerTest
,
946 ConnectWithNoContentHandlerGetsInvalidContentHandlerId
) {
947 application_manager_
->SetLoaderForScheme(
948 scoped_ptr
<ApplicationLoader
>(new TestApplicationLoader
), "test");
950 uint32_t content_handler_id
= 1u;
951 scoped_ptr
<ConnectToApplicationParams
> params(new ConnectToApplicationParams
);
952 params
->SetURLInfo(GURL("test:test"));
953 params
->set_filter(GetPermissiveCapabilityFilter());
954 params
->set_connect_callback(
955 [&content_handler_id
](uint32_t t
) { content_handler_id
= t
; });
956 application_manager_
->ConnectToApplication(params
.Pass());
957 EXPECT_EQ(0u, content_handler_id
);