Roll src/third_party/WebKit fe3d0ed:840e60d (svn 202350:202351)
[chromium-blink-merge.git] / mojo / shell / application_manager_unittest.cc
blobb0b55e4457ce1948279b23a10b86f5fc606d2dc7
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"
6 #include "base/bind.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"
25 namespace mojo {
26 namespace shell {
27 namespace {
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 {
36 public:
37 TestMimeTypeFetcher(const FetchCallback& fetch_callback,
38 const GURL& url,
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 {}
45 // Fetcher:
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();
53 void AsPath(
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; }
60 private:
61 const GURL url_;
62 const std::string mime_type_;
64 DISALLOW_COPY_AND_ASSIGN(TestMimeTypeFetcher);
67 struct TestContext {
68 TestContext() : num_impls(0), num_loader_deletes(0) {}
69 std::string last_test_string;
70 int num_impls;
71 int num_loader_deletes;
74 void QuitClosure(bool* value) {
75 *value = true;
76 base::MessageLoop::current()->QuitWhenIdle();
79 class TestServiceImpl : public TestService {
80 public:
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())
89 return;
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;
97 callback.Run();
100 private:
101 TestContext* context_;
102 StrongBinding<TestService> binding_;
105 class TestClient {
106 public:
107 explicit TestClient(TestServicePtr service)
108 : service_(service.Pass()), quit_after_ack_(false) {}
110 void AckTest() {
111 if (quit_after_ack_)
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)));
121 private:
122 TestServicePtr service_;
123 bool quit_after_ack_;
124 DISALLOW_COPY_AND_ASSIGN(TestClient);
127 class TestContentHandler : public ContentHandler, public ApplicationDelegate {
128 public:
129 TestContentHandler(ApplicationConnection* connection,
130 InterfaceRequest<ContentHandler> request)
131 : binding_(this, request.Pass()) {}
133 // ContentHandler:
134 void StartApplication(InterfaceRequest<Application> application_request,
135 URLResponsePtr response) override {
136 apps_.push_back(new ApplicationImpl(this, application_request.Pass()));
139 private:
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> {
150 public:
151 TestApplicationLoader()
152 : context_(nullptr), num_loads_(0), create_content_handler_(false) {}
154 ~TestApplicationLoader() override {
155 if (context_)
156 ++context_->num_loader_deletes;
157 test_app_.reset();
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_; }
168 private:
169 // ApplicationLoader implementation.
170 void Load(const GURL& url,
171 InterfaceRequest<Application> application_request) override {
172 ++num_loads_;
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());
182 return true;
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_;
199 int num_loads_;
200 GURL last_requestor_url_;
201 bool create_content_handler_;
203 DISALLOW_COPY_AND_ASSIGN(TestApplicationLoader);
206 class ClosingApplicationLoader : public ApplicationLoader {
207 private:
208 // ApplicationLoader implementation.
209 void Load(const GURL& url,
210 InterfaceRequest<Application> application_request) override {}
213 class TesterContext {
214 public:
215 explicit TesterContext(base::MessageLoop* loop)
216 : num_b_calls_(0),
217 num_c_calls_(0),
218 num_a_deletes_(0),
219 num_b_deletes_(0),
220 num_c_deletes_(0),
221 tester_called_quit_(false),
222 a_called_quit_(false),
223 loop_(loop) {}
225 void IncrementNumBCalls() {
226 base::AutoLock lock(lock_);
227 num_b_calls_++;
230 void IncrementNumCCalls() {
231 base::AutoLock lock(lock_);
232 num_c_calls_++;
235 void IncrementNumADeletes() {
236 base::AutoLock lock(lock_);
237 num_a_deletes_++;
240 void IncrementNumBDeletes() {
241 base::AutoLock lock(lock_);
242 num_b_deletes_++;
245 void IncrementNumCDeletes() {
246 base::AutoLock lock(lock_);
247 num_c_deletes_++;
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;
260 int num_b_calls() {
261 base::AutoLock lock(lock_);
262 return num_b_calls_;
264 int num_c_calls() {
265 base::AutoLock lock(lock_);
266 return num_c_calls_;
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_;
289 void QuitSoon() {
290 loop_->PostTask(FROM_HERE, base::MessageLoop::QuitWhenIdleClosure());
293 private:
294 // lock_ protects all members except for loop_ which must be unchanged for the
295 // lifetime of this class.
296 base::Lock lock_;
297 int num_b_calls_;
298 int num_c_calls_;
299 int num_a_deletes_;
300 int num_b_deletes_;
301 int num_c_deletes_;
302 bool tester_called_quit_;
303 bool a_called_quit_;
305 base::MessageLoop* loop_;
308 // Used to test that the requestor url will be correctly passed.
309 class TestAImpl : public TestA {
310 public:
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())
324 Quit();
327 private:
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)));
336 void Quit() {
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_;
344 TestBPtr b_;
345 StrongBinding<TestA> binding_;
348 class TestBImpl : public TestB {
349 public:
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();
364 private:
365 void B(const Callback<void()>& callback) override {
366 test_context_->IncrementNumBCalls();
367 callback.Run();
370 void CallC(const Callback<void()>& callback) override {
371 test_context_->IncrementNumBCalls();
372 c_->C(callback);
375 TesterContext* test_context_;
376 TestCPtr c_;
377 StrongBinding<TestB> binding_;
380 class TestCImpl : public TestC {
381 public:
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(); }
389 private:
390 void C(const Callback<void()>& callback) override {
391 test_context_->IncrementNumCCalls();
392 callback.Run();
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> {
404 public:
405 Tester(TesterContext* context, const std::string& requestor_url)
406 : context_(context), requestor_url_(requestor_url) {}
407 ~Tester() override {}
409 private:
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();
421 return false;
423 // If we're coming from A, then add B, otherwise A.
424 if (connection->GetRemoteApplicationURL() == kTestAURLString)
425 connection->AddService<TestB>(this);
426 else
427 connection->AddService<TestA>(this);
428 return true;
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);
435 return true;
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 {
460 public:
461 TestApplicationFetcher()
462 : create_test_fetcher_(false),
463 fetcher_url_("xxx"),
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);
485 return resolved_url;
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_);
493 private:
494 bool create_test_fetcher_;
495 GURL fetcher_url_;
496 std::string mime_type_;
498 DISALLOW_COPY_AND_ASSIGN(TestApplicationFetcher);
501 class ApplicationManagerTest : public testing::Test {
502 public:
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),
517 &service_proxy);
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);
536 protected:
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");
549 loop_.Run();
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)));
556 loop_.Run();
557 EXPECT_EQ(1, context_.num_impls);
558 test_client_.reset();
559 loop_.Run();
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),
579 GURL("test:test1"));
580 am.SetLoaderForURL(scoped_ptr<ApplicationLoader>(url_loader2),
581 GURL("test:test1"));
582 am.SetLoaderForScheme(scoped_ptr<ApplicationLoader>(scheme_loader1),
583 "test");
584 am.SetLoaderForScheme(scoped_ptr<ApplicationLoader>(scheme_loader2),
585 "test");
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
623 // it loads.
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);
631 TestAPtr a;
632 application_manager_->ConnectToService(GURL(kTestAURLString), &a);
633 a->CallB();
634 loop_.Run();
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);
647 TestAPtr a;
648 application_manager_->ConnectToService(GURL(kTestAURLString), &a);
649 a->CallCFromB();
650 loop_.Run();
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
658 // it goes away.
659 TEST_F(ApplicationManagerTest, BDeleted) {
660 AddLoaderForURL(GURL(kTestAURLString), std::string());
661 AddLoaderForURL(GURL(kTestBURLString), std::string());
663 TestAPtr a;
664 application_manager_->ConnectToService(GURL(kTestAURLString), &a);
666 a->CallB();
667 loop_.Run();
669 // Kills the a app.
670 application_manager_->SetLoaderForURL(scoped_ptr<ApplicationLoader>(),
671 GURL(kTestAURLString));
672 loop_.Run();
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");
686 TestAPtr a;
687 application_manager_->ConnectToService(GURL(kTestAURLString), &a);
688 a->CallB();
689 loop_.Run();
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).
701 TestCPtr c;
702 application_manager_->ConnectToService(GURL(kTestAURLString), &c);
703 c.set_connection_error_handler(
704 []() { base::MessageLoop::current()->QuitWhenIdle(); });
706 loop_.Run();
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"),
721 &test_service);
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"),
727 &test_service);
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");
737 bool called = false;
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());
744 loop_.Run();
745 EXPECT_TRUE(called);
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);
766 bool called = false;
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());
775 loop.Run();
776 EXPECT_TRUE(called);
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"),
788 &test_service);
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"),
793 &test_service);
794 EXPECT_EQ(2, test_loader_->num_loads());
796 // The same identity as the one above because only the query string is
797 // different.
798 application_manager_->ConnectToService(GURL("http://www.example.org/abc"),
799 &test_service);
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;
846 run_loop.Quit();
848 application_manager.ConnectToApplication(params.Pass());
849 run_loop.Run();
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;
864 run_loop.Quit();
866 application_manager.ConnectToApplication(params.Pass());
867 run_loop.Run();
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;
905 run_loop.Quit();
907 application_manager.ConnectToApplication(params.Pass());
908 run_loop.Run();
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;
936 run_loop.Quit();
938 application_manager.ConnectToApplication(params.Pass());
939 run_loop.Run();
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);
960 } // namespace
961 } // namespace shell
962 } // namespace mojo