Makes content handlers see requestor url
[chromium-blink-merge.git] / mojo / shell / application_manager_unittest.cc
blobd77a9aad84a7dec3aee36b50eadd3a22b8396aff
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 "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"
22 namespace mojo {
23 namespace shell {
24 namespace {
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 {
33 public:
34 explicit TestMimeTypeFetcher(const FetchCallback& fetch_callback)
35 : Fetcher(fetch_callback), url_("xxx") {
36 loader_callback_.Run(make_scoped_ptr(this));
38 ~TestMimeTypeFetcher() override {}
40 // Fetcher:
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();
47 void AsPath(
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; }
54 private:
55 const GURL url_;
57 DISALLOW_COPY_AND_ASSIGN(TestMimeTypeFetcher);
60 struct TestContext {
61 TestContext() : num_impls(0), num_loader_deletes(0) {}
62 std::string last_test_string;
63 int num_impls;
64 int num_loader_deletes;
67 void QuitClosure(bool* value) {
68 *value = true;
69 base::MessageLoop::current()->QuitWhenIdle();
72 class QuitMessageLoopErrorHandler : public ErrorHandler {
73 public:
74 QuitMessageLoopErrorHandler() {}
75 ~QuitMessageLoopErrorHandler() override {}
77 // |ErrorHandler| implementation:
78 void OnConnectionError() override {
79 base::MessageLoop::current()->QuitWhenIdle();
82 private:
83 DISALLOW_COPY_AND_ASSIGN(QuitMessageLoopErrorHandler);
86 class TestServiceImpl : public TestService {
87 public:
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())
96 return;
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;
104 callback.Run();
107 private:
108 TestContext* context_;
109 StrongBinding<TestService> binding_;
112 class TestClient {
113 public:
114 explicit TestClient(TestServicePtr service)
115 : service_(service.Pass()), quit_after_ack_(false) {}
117 void AckTest() {
118 if (quit_after_ack_)
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)));
128 private:
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> {
137 public:
138 TestApplicationLoader() : context_(nullptr), num_loads_(0) {}
140 ~TestApplicationLoader() override {
141 if (context_)
142 ++context_->num_loader_deletes;
143 test_app_.reset();
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_; }
151 private:
152 // ApplicationLoader implementation.
153 void Load(const GURL& url,
154 InterfaceRequest<Application> application_request) override {
155 ++num_loads_;
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());
163 return true;
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_;
174 int num_loads_;
175 GURL last_requestor_url_;
177 DISALLOW_COPY_AND_ASSIGN(TestApplicationLoader);
180 class ClosingApplicationLoader : public ApplicationLoader {
181 private:
182 // ApplicationLoader implementation.
183 void Load(const GURL& url,
184 InterfaceRequest<Application> application_request) override {}
187 class TesterContext {
188 public:
189 explicit TesterContext(base::MessageLoop* loop)
190 : num_b_calls_(0),
191 num_c_calls_(0),
192 num_a_deletes_(0),
193 num_b_deletes_(0),
194 num_c_deletes_(0),
195 tester_called_quit_(false),
196 a_called_quit_(false),
197 loop_(loop) {}
199 void IncrementNumBCalls() {
200 base::AutoLock lock(lock_);
201 num_b_calls_++;
204 void IncrementNumCCalls() {
205 base::AutoLock lock(lock_);
206 num_c_calls_++;
209 void IncrementNumADeletes() {
210 base::AutoLock lock(lock_);
211 num_a_deletes_++;
214 void IncrementNumBDeletes() {
215 base::AutoLock lock(lock_);
216 num_b_deletes_++;
219 void IncrementNumCDeletes() {
220 base::AutoLock lock(lock_);
221 num_c_deletes_++;
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;
234 int num_b_calls() {
235 base::AutoLock lock(lock_);
236 return num_b_calls_;
238 int num_c_calls() {
239 base::AutoLock lock(lock_);
240 return num_c_calls_;
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_;
263 void QuitSoon() {
264 loop_->PostTask(FROM_HERE, base::MessageLoop::QuitWhenIdleClosure());
267 private:
268 // lock_ protects all members except for loop_ which must be unchanged for the
269 // lifetime of this class.
270 base::Lock lock_;
271 int num_b_calls_;
272 int num_c_calls_;
273 int num_a_deletes_;
274 int num_b_deletes_;
275 int num_c_deletes_;
276 bool tester_called_quit_;
277 bool a_called_quit_;
279 base::MessageLoop* loop_;
282 // Used to test that the requestor url will be correctly passed.
283 class TestAImpl : public TestA {
284 public:
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())
295 Quit();
298 private:
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)));
307 void Quit() {
308 base::MessageLoop::current()->Quit();
309 test_context_->set_a_called_quit();
310 test_context_->QuitSoon();
313 TesterContext* test_context_;
314 TestBPtr b_;
315 StrongBinding<TestA> binding_;
318 class TestBImpl : public TestB {
319 public:
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();
334 private:
335 void B(const Callback<void()>& callback) override {
336 test_context_->IncrementNumBCalls();
337 callback.Run();
340 void CallC(const Callback<void()>& callback) override {
341 test_context_->IncrementNumBCalls();
342 c_->C(callback);
345 TesterContext* test_context_;
346 TestCPtr c_;
347 StrongBinding<TestB> binding_;
350 class TestCImpl : public TestC {
351 public:
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(); }
359 private:
360 void C(const Callback<void()>& callback) override {
361 test_context_->IncrementNumCCalls();
362 callback.Run();
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> {
374 public:
375 Tester(TesterContext* context, const std::string& requestor_url)
376 : context_(context), requestor_url_(requestor_url) {}
377 ~Tester() override {}
379 private:
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();
391 return false;
393 // If we're coming from A, then add B, otherwise A.
394 if (connection->GetRemoteApplicationURL() == kTestAURLString)
395 connection->AddService<TestB>(this);
396 else
397 connection->AddService<TestA>(this);
398 return true;
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);
405 return true;
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 {
430 public:
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())
444 return it->second;
445 return url;
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);
455 return mapped_url;
457 bool CreateFetcher(const GURL& url,
458 const Fetcher::FetchCallback& loader_callback) override {
459 if (!create_test_fetcher_)
460 return false;
461 new TestMimeTypeFetcher(loader_callback);
462 return true;
465 private:
466 std::map<GURL, GURL> mappings_;
467 bool create_test_fetcher_;
469 DISALLOW_COPY_AND_ASSIGN(TestDelegate);
472 class ApplicationManagerTest : public testing::Test {
473 public:
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),
487 &service_proxy);
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);
506 protected:
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");
520 loop_.Run();
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");
535 loop_.Run();
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");
555 loop_.Run();
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");
563 loop_.Run();
567 TEST_F(ApplicationManagerTest, ClientError) {
568 test_client_->Test("test");
569 EXPECT_TRUE(HasFactoryForURL(GURL(kTestURLString)));
570 loop_.Run();
571 EXPECT_EQ(1, context_.num_impls);
572 test_client_.reset();
573 loop_.Run();
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),
593 GURL("test:test1"));
594 am.SetLoaderForURL(scoped_ptr<ApplicationLoader>(url_loader2),
595 GURL("test:test1"));
596 am.SetLoaderForScheme(scoped_ptr<ApplicationLoader>(scheme_loader1),
597 "test");
598 am.SetLoaderForScheme(scoped_ptr<ApplicationLoader>(scheme_loader2),
599 "test");
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
637 // it loads.
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);
645 TestAPtr a;
646 application_manager_->ConnectToService(GURL(kTestAURLString), &a);
647 a->CallB();
648 loop_.Run();
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);
661 TestAPtr a;
662 application_manager_->ConnectToService(GURL(kTestAURLString), &a);
663 a->CallCFromB();
664 loop_.Run();
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
672 // it goes away.
673 TEST_F(ApplicationManagerTest, BDeleted) {
674 AddLoaderForURL(GURL(kTestAURLString), std::string());
675 AddLoaderForURL(GURL(kTestBURLString), std::string());
677 TestAPtr a;
678 application_manager_->ConnectToService(GURL(kTestAURLString), &a);
680 a->CallB();
681 loop_.Run();
683 // Kills the a app.
684 application_manager_->SetLoaderForURL(scoped_ptr<ApplicationLoader>(),
685 GURL(kTestAURLString));
686 loop_.Run();
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");
700 TestAPtr a;
701 application_manager_->ConnectToService(GURL(kTestAURLString), &a);
702 a->CallB();
703 loop_.Run();
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).
715 TestCPtr c;
716 application_manager_->ConnectToService(GURL(kTestAURLString), &c);
717 QuitMessageLoopErrorHandler quitter;
718 c.set_error_handler(&quitter);
720 loop_.Run();
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;
744 TestContext context;
745 custom_loader->set_context(&context);
746 application_manager_->SetLoaderForURL(make_scoped_ptr(custom_loader),
747 GURL("mojo:foo"));
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"),
770 &test_service);
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"),
776 &test_service);
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");
786 bool called = false;
787 application_manager_->ConnectToApplication(
788 GURL("test:test"), GURL(), nullptr, nullptr,
789 base::Bind(&QuitClosure, base::Unretained(&called)));
790 loop_.Run();
791 EXPECT_TRUE(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);
811 bool called = false;
812 application_manager.ConnectToApplication(
813 GURL("test:test"), requestor_url, nullptr, nullptr,
814 base::Bind(&QuitClosure, base::Unretained(&called)));
815 loop.Run();
816 EXPECT_TRUE(called);
818 ASSERT_EQ(1, loader->num_loads());
819 EXPECT_EQ(requestor_url, loader->last_requestor_url());
822 } // namespace
823 } // namespace shell
824 } // namespace mojo