gn: 'platform_impl' should be a group instead of component (since it has no code...
[chromium-blink-merge.git] / mojo / shell / application_manager_unittest.cc
blobbc32a39f0b7f91e175f58c07c691d2189f366178
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/application/public/cpp/application_connection.h"
11 #include "mojo/application/public/cpp/application_delegate.h"
12 #include "mojo/application/public/cpp/application_impl.h"
13 #include "mojo/application/public/cpp/interface_factory.h"
14 #include "mojo/application/public/interfaces/service_provider.mojom.h"
15 #include "mojo/public/cpp/bindings/strong_binding.h"
16 #include "mojo/shell/application_loader.h"
17 #include "mojo/shell/application_manager.h"
18 #include "mojo/shell/fetcher.h"
19 #include "mojo/shell/test.mojom.h"
20 #include "testing/gtest/include/gtest/gtest.h"
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 GURL GetRedirectReferer() const override { return GURL(); }
44 URLResponsePtr AsURLResponse(base::TaskRunner* task_runner,
45 uint32_t skip) override {
46 return URLResponse::New().Pass();
48 void AsPath(
49 base::TaskRunner* task_runner,
50 base::Callback<void(const base::FilePath&, bool)> callback) override {}
51 std::string MimeType() override { return kTestMimeType; }
52 bool HasMojoMagic() override { return false; }
53 bool PeekFirstLine(std::string* line) override { return false; }
55 private:
56 const GURL url_;
58 DISALLOW_COPY_AND_ASSIGN(TestMimeTypeFetcher);
61 struct TestContext {
62 TestContext() : num_impls(0), num_loader_deletes(0) {}
63 std::string last_test_string;
64 int num_impls;
65 int num_loader_deletes;
68 void QuitClosure(bool* value) {
69 *value = true;
70 base::MessageLoop::current()->QuitWhenIdle();
73 class QuitMessageLoopErrorHandler : public ErrorHandler {
74 public:
75 QuitMessageLoopErrorHandler() {}
76 ~QuitMessageLoopErrorHandler() override {}
78 // |ErrorHandler| implementation:
79 void OnConnectionError() override {
80 base::MessageLoop::current()->QuitWhenIdle();
83 private:
84 DISALLOW_COPY_AND_ASSIGN(QuitMessageLoopErrorHandler);
87 class TestServiceImpl : public TestService {
88 public:
89 TestServiceImpl(TestContext* context, InterfaceRequest<TestService> request)
90 : context_(context), binding_(this, request.Pass()) {
91 ++context_->num_impls;
94 ~TestServiceImpl() override {
95 --context_->num_impls;
96 if (!base::MessageLoop::current()->is_running())
97 return;
98 base::MessageLoop::current()->Quit();
101 // TestService implementation:
102 void Test(const String& test_string,
103 const Callback<void()>& callback) override {
104 context_->last_test_string = test_string;
105 callback.Run();
108 private:
109 TestContext* context_;
110 StrongBinding<TestService> binding_;
113 class TestClient {
114 public:
115 explicit TestClient(TestServicePtr service)
116 : service_(service.Pass()), quit_after_ack_(false) {}
118 void AckTest() {
119 if (quit_after_ack_)
120 base::MessageLoop::current()->Quit();
123 void Test(const std::string& test_string) {
124 quit_after_ack_ = true;
125 service_->Test(test_string,
126 base::Bind(&TestClient::AckTest, base::Unretained(this)));
129 private:
130 TestServicePtr service_;
131 bool quit_after_ack_;
132 DISALLOW_COPY_AND_ASSIGN(TestClient);
135 class TestApplicationLoader : public ApplicationLoader,
136 public ApplicationDelegate,
137 public InterfaceFactory<TestService> {
138 public:
139 TestApplicationLoader() : context_(nullptr), num_loads_(0) {}
141 ~TestApplicationLoader() override {
142 if (context_)
143 ++context_->num_loader_deletes;
144 test_app_.reset();
147 void set_context(TestContext* context) { context_ = context; }
148 int num_loads() const { return num_loads_; }
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 mojo::URLRequestPtr request2(mojo::URLRequest::New());
290 request2->url = mojo::String::From(kTestBURLString);
291 app_impl->ConnectToApplication(request2.Pass())->ConnectToService(&b_);
294 ~TestAImpl() override {
295 test_context_->IncrementNumADeletes();
296 if (base::MessageLoop::current()->is_running())
297 Quit();
300 private:
301 void CallB() override {
302 b_->B(base::Bind(&TestAImpl::Quit, base::Unretained(this)));
305 void CallCFromB() override {
306 b_->CallC(base::Bind(&TestAImpl::Quit, base::Unretained(this)));
309 void Quit() {
310 base::MessageLoop::current()->Quit();
311 test_context_->set_a_called_quit();
312 test_context_->QuitSoon();
315 TesterContext* test_context_;
316 TestBPtr b_;
317 StrongBinding<TestA> binding_;
320 class TestBImpl : public TestB {
321 public:
322 TestBImpl(ApplicationConnection* connection,
323 TesterContext* test_context,
324 InterfaceRequest<TestB> request)
325 : test_context_(test_context), binding_(this, request.Pass()) {
326 connection->ConnectToService(&c_);
329 ~TestBImpl() override {
330 test_context_->IncrementNumBDeletes();
331 if (base::MessageLoop::current()->is_running())
332 base::MessageLoop::current()->Quit();
333 test_context_->QuitSoon();
336 private:
337 void B(const Callback<void()>& callback) override {
338 test_context_->IncrementNumBCalls();
339 callback.Run();
342 void CallC(const Callback<void()>& callback) override {
343 test_context_->IncrementNumBCalls();
344 c_->C(callback);
347 TesterContext* test_context_;
348 TestCPtr c_;
349 StrongBinding<TestB> binding_;
352 class TestCImpl : public TestC {
353 public:
354 TestCImpl(ApplicationConnection* connection,
355 TesterContext* test_context,
356 InterfaceRequest<TestC> request)
357 : test_context_(test_context), binding_(this, request.Pass()) {}
359 ~TestCImpl() override { test_context_->IncrementNumCDeletes(); }
361 private:
362 void C(const Callback<void()>& callback) override {
363 test_context_->IncrementNumCCalls();
364 callback.Run();
367 TesterContext* test_context_;
368 StrongBinding<TestC> binding_;
371 class Tester : public ApplicationDelegate,
372 public ApplicationLoader,
373 public InterfaceFactory<TestA>,
374 public InterfaceFactory<TestB>,
375 public InterfaceFactory<TestC> {
376 public:
377 Tester(TesterContext* context, const std::string& requestor_url)
378 : context_(context), requestor_url_(requestor_url) {}
379 ~Tester() override {}
381 private:
382 void Load(const GURL& url,
383 InterfaceRequest<Application> application_request) override {
384 app_.reset(new ApplicationImpl(this, application_request.Pass()));
387 bool ConfigureIncomingConnection(ApplicationConnection* connection) override {
388 if (!requestor_url_.empty() &&
389 requestor_url_ != connection->GetRemoteApplicationURL()) {
390 context_->set_tester_called_quit();
391 context_->QuitSoon();
392 base::MessageLoop::current()->Quit();
393 return false;
395 // If we're coming from A, then add B, otherwise A.
396 if (connection->GetRemoteApplicationURL() == kTestAURLString)
397 connection->AddService<TestB>(this);
398 else
399 connection->AddService<TestA>(this);
400 return true;
403 bool ConfigureOutgoingConnection(ApplicationConnection* connection) override {
404 // If we're connecting to B, then add C.
405 if (connection->GetRemoteApplicationURL() == kTestBURLString)
406 connection->AddService<TestC>(this);
407 return true;
410 void Create(ApplicationConnection* connection,
411 InterfaceRequest<TestA> request) override {
412 a_bindings_.push_back(new TestAImpl(app_.get(), context_, request.Pass()));
415 void Create(ApplicationConnection* connection,
416 InterfaceRequest<TestB> request) override {
417 new TestBImpl(connection, context_, request.Pass());
420 void Create(ApplicationConnection* connection,
421 InterfaceRequest<TestC> request) override {
422 new TestCImpl(connection, context_, request.Pass());
425 TesterContext* context_;
426 scoped_ptr<ApplicationImpl> app_;
427 std::string requestor_url_;
428 ScopedVector<TestAImpl> a_bindings_;
431 class TestDelegate : public ApplicationManager::Delegate {
432 public:
433 TestDelegate() : create_test_fetcher_(false) {}
434 ~TestDelegate() override {}
436 void AddMapping(const GURL& from, const GURL& to) { mappings_[from] = to; }
438 void set_create_test_fetcher(bool create_test_fetcher) {
439 create_test_fetcher_ = create_test_fetcher;
442 // ApplicationManager::Delegate
443 GURL ResolveMappings(const GURL& url) override {
444 auto it = mappings_.find(url);
445 if (it != mappings_.end())
446 return it->second;
447 return url;
449 GURL ResolveMojoURL(const GURL& url) override {
450 GURL mapped_url = ResolveMappings(url);
451 // The shell automatically map mojo URLs.
452 if (mapped_url.scheme() == "mojo") {
453 url::Replacements<char> replacements;
454 replacements.SetScheme("file", url::Component(0, 4));
455 mapped_url = mapped_url.ReplaceComponents(replacements);
457 return mapped_url;
459 bool CreateFetcher(const GURL& url,
460 const Fetcher::FetchCallback& loader_callback) override {
461 if (!create_test_fetcher_)
462 return false;
463 new TestMimeTypeFetcher(loader_callback);
464 return true;
467 private:
468 std::map<GURL, GURL> mappings_;
469 bool create_test_fetcher_;
471 DISALLOW_COPY_AND_ASSIGN(TestDelegate);
474 class ApplicationManagerTest : public testing::Test {
475 public:
476 ApplicationManagerTest() : tester_context_(&loop_) {}
478 ~ApplicationManagerTest() override {}
480 void SetUp() override {
481 application_manager_.reset(new ApplicationManager(&test_delegate_));
482 test_loader_ = new TestApplicationLoader;
483 test_loader_->set_context(&context_);
484 application_manager_->set_default_loader(
485 scoped_ptr<ApplicationLoader>(test_loader_));
487 TestServicePtr service_proxy;
488 application_manager_->ConnectToService(GURL(kTestURLString),
489 &service_proxy);
490 test_client_.reset(new TestClient(service_proxy.Pass()));
493 void TearDown() override {
494 test_client_.reset();
495 application_manager_.reset();
498 void AddLoaderForURL(const GURL& url, const std::string& requestor_url) {
499 application_manager_->SetLoaderForURL(
500 make_scoped_ptr(new Tester(&tester_context_, requestor_url)), url);
503 bool HasFactoryForURL(const GURL& url) {
504 ApplicationManager::TestAPI manager_test_api(application_manager_.get());
505 return manager_test_api.HasFactoryForURL(url);
508 protected:
509 base::ShadowingAtExitManager at_exit_;
510 TestDelegate test_delegate_;
511 TestApplicationLoader* test_loader_;
512 TesterContext tester_context_;
513 TestContext context_;
514 base::MessageLoop loop_;
515 scoped_ptr<TestClient> test_client_;
516 scoped_ptr<ApplicationManager> application_manager_;
517 DISALLOW_COPY_AND_ASSIGN(ApplicationManagerTest);
520 TEST_F(ApplicationManagerTest, Basic) {
521 test_client_->Test("test");
522 loop_.Run();
523 EXPECT_EQ(std::string("test"), context_.last_test_string);
526 // Confirm that url mappings are respected.
527 TEST_F(ApplicationManagerTest, URLMapping) {
528 ApplicationManager am(&test_delegate_);
529 GURL test_url("test:test");
530 GURL test_url2("test:test2");
531 test_delegate_.AddMapping(test_url, test_url2);
532 TestApplicationLoader* loader = new TestApplicationLoader;
533 loader->set_context(&context_);
534 am.SetLoaderForURL(scoped_ptr<ApplicationLoader>(loader), test_url2);
536 // Connext to the mapped url
537 TestServicePtr test_service;
538 am.ConnectToService(test_url, &test_service);
539 TestClient test_client(test_service.Pass());
540 test_client.Test("test");
541 loop_.Run();
544 // Connext to the target url
545 TestServicePtr test_service;
546 am.ConnectToService(test_url2, &test_service);
547 TestClient test_client(test_service.Pass());
548 test_client.Test("test");
549 loop_.Run();
553 TEST_F(ApplicationManagerTest, ClientError) {
554 test_client_->Test("test");
555 EXPECT_TRUE(HasFactoryForURL(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(HasFactoryForURL(GURL(kTestURLString)));
564 TEST_F(ApplicationManagerTest, Deletes) {
566 ApplicationManager am(&test_delegate_);
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 QuitMessageLoopErrorHandler quitter;
704 c.set_error_handler(&quitter);
706 loop_.Run();
707 EXPECT_TRUE(c.encountered_error());
710 TEST_F(ApplicationManagerTest, MappedURLsShouldNotCauseDuplicateLoad) {
711 test_delegate_.AddMapping(GURL("foo:foo2"), GURL("foo:foo"));
712 // 1 because ApplicationManagerTest connects once at startup.
713 EXPECT_EQ(1, test_loader_->num_loads());
715 TestServicePtr test_service;
716 application_manager_->ConnectToService(GURL("foo:foo"), &test_service);
717 EXPECT_EQ(2, test_loader_->num_loads());
719 TestServicePtr test_service2;
720 application_manager_->ConnectToService(GURL("foo:foo2"), &test_service2);
721 EXPECT_EQ(2, test_loader_->num_loads());
723 TestServicePtr test_service3;
724 application_manager_->ConnectToService(GURL("bar:bar"), &test_service2);
725 EXPECT_EQ(3, test_loader_->num_loads());
728 TEST_F(ApplicationManagerTest, MappedURLsShouldWorkWithLoaders) {
729 TestApplicationLoader* custom_loader = new TestApplicationLoader;
730 TestContext context;
731 custom_loader->set_context(&context);
732 application_manager_->SetLoaderForURL(make_scoped_ptr(custom_loader),
733 GURL("mojo:foo"));
734 test_delegate_.AddMapping(GURL("mojo:foo2"), GURL("mojo:foo"));
736 TestServicePtr test_service;
737 application_manager_->ConnectToService(GURL("mojo:foo2"), &test_service);
738 EXPECT_EQ(1, custom_loader->num_loads());
739 custom_loader->set_context(nullptr);
741 EXPECT_TRUE(HasFactoryForURL(GURL("mojo:foo2")));
742 EXPECT_FALSE(HasFactoryForURL(GURL("mojo:foo")));
745 TEST_F(ApplicationManagerTest, TestQueryWithLoaders) {
746 TestApplicationLoader* url_loader = new TestApplicationLoader;
747 TestApplicationLoader* scheme_loader = new TestApplicationLoader;
748 application_manager_->SetLoaderForURL(
749 scoped_ptr<ApplicationLoader>(url_loader), GURL("test:test1"));
750 application_manager_->SetLoaderForScheme(
751 scoped_ptr<ApplicationLoader>(scheme_loader), "test");
753 // test::test1 should go to url_loader.
754 TestServicePtr test_service;
755 application_manager_->ConnectToService(GURL("test:test1?foo=bar"),
756 &test_service);
757 EXPECT_EQ(1, url_loader->num_loads());
758 EXPECT_EQ(0, scheme_loader->num_loads());
760 // test::test2 should go to scheme loader.
761 application_manager_->ConnectToService(GURL("test:test2?foo=bar"),
762 &test_service);
763 EXPECT_EQ(1, url_loader->num_loads());
764 EXPECT_EQ(1, scheme_loader->num_loads());
767 TEST_F(ApplicationManagerTest, TestEndApplicationClosure) {
768 ClosingApplicationLoader* loader = new ClosingApplicationLoader();
769 application_manager_->SetLoaderForScheme(
770 scoped_ptr<ApplicationLoader>(loader), "test");
772 bool called = false;
773 mojo::URLRequestPtr request(mojo::URLRequest::New());
774 request->url = mojo::String::From("test:test");
775 application_manager_->ConnectToApplication(
776 request.Pass(), GURL(), nullptr, nullptr,
777 base::Bind(&QuitClosure, base::Unretained(&called)));
778 loop_.Run();
779 EXPECT_TRUE(called);
782 TEST(ApplicationManagerTest2, ContentHandlerConnectionGetsRequestorURL) {
783 const GURL content_handler_url("http://test.content.handler");
784 const GURL requestor_url("http://requestor.url");
785 TestContext test_context;
786 base::MessageLoop loop;
787 TestDelegate test_delegate;
788 test_delegate.set_create_test_fetcher(true);
789 ApplicationManager application_manager(&test_delegate);
790 application_manager.set_default_loader(nullptr);
791 application_manager.RegisterContentHandler(kTestMimeType,
792 content_handler_url);
794 TestApplicationLoader* loader = new TestApplicationLoader;
795 loader->set_context(&test_context);
796 application_manager.SetLoaderForURL(scoped_ptr<ApplicationLoader>(loader),
797 content_handler_url);
799 bool called = false;
800 mojo::URLRequestPtr request(mojo::URLRequest::New());
801 request->url = mojo::String::From("test:test");
802 application_manager.ConnectToApplication(
803 request.Pass(), requestor_url, nullptr, nullptr,
804 base::Bind(&QuitClosure, base::Unretained(&called)));
805 loop.Run();
806 EXPECT_TRUE(called);
808 ASSERT_EQ(1, loader->num_loads());
809 EXPECT_EQ(requestor_url, loader->last_requestor_url());
812 } // namespace
813 } // namespace shell
814 } // namespace mojo