Add MB configs for the chromium.chrome waterfall.
[chromium-blink-merge.git] / mojo / shell / application_manager_unittest.cc
blobc626b01e557fd0a5c0605e6ff12b388eee6218f3
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_loader.h"
19 #include "mojo/shell/application_manager.h"
20 #include "mojo/shell/connect_util.h"
21 #include "mojo/shell/fetcher.h"
22 #include "mojo/shell/test.mojom.h"
23 #include "mojo/shell/test_package_manager.h"
24 #include "testing/gtest/include/gtest/gtest.h"
26 namespace mojo {
27 namespace shell {
28 namespace {
30 const char kTestURLString[] = "test:testService";
31 const char kTestAURLString[] = "test:TestA";
32 const char kTestBURLString[] = "test:TestB";
34 const char kTestMimeType[] = "test/mime-type";
36 class TestMimeTypeFetcher : public Fetcher {
37 public:
38 TestMimeTypeFetcher(const FetchCallback& fetch_callback,
39 const GURL& url,
40 const std::string& mime_type)
41 : Fetcher(fetch_callback), url_(url), mime_type_(mime_type) {
42 loader_callback_.Run(make_scoped_ptr(this));
44 ~TestMimeTypeFetcher() override {}
46 // Fetcher:
47 const GURL& GetURL() const override { return url_; }
48 GURL GetRedirectURL() const override { return GURL("yyy"); }
49 GURL GetRedirectReferer() const override { return GURL(); }
50 URLResponsePtr AsURLResponse(base::TaskRunner* task_runner,
51 uint32_t skip) override {
52 return URLResponse::New().Pass();
54 void AsPath(
55 base::TaskRunner* task_runner,
56 base::Callback<void(const base::FilePath&, bool)> callback) override {}
57 std::string MimeType() override { return mime_type_; }
58 bool HasMojoMagic() override { return false; }
59 bool PeekFirstLine(std::string* line) override { return false; }
61 private:
62 const GURL url_;
63 const std::string mime_type_;
65 DISALLOW_COPY_AND_ASSIGN(TestMimeTypeFetcher);
68 struct TestContext {
69 TestContext() : num_impls(0), num_loader_deletes(0) {}
70 std::string last_test_string;
71 int num_impls;
72 int num_loader_deletes;
75 void QuitClosure(bool* value) {
76 *value = true;
77 base::MessageLoop::current()->QuitWhenIdle();
80 class TestServiceImpl : public TestService {
81 public:
82 TestServiceImpl(TestContext* context, InterfaceRequest<TestService> request)
83 : context_(context), binding_(this, request.Pass()) {
84 ++context_->num_impls;
87 ~TestServiceImpl() override {
88 --context_->num_impls;
89 if (!base::MessageLoop::current()->is_running())
90 return;
91 base::MessageLoop::current()->Quit();
94 // TestService implementation:
95 void Test(const String& test_string,
96 const Callback<void()>& callback) override {
97 context_->last_test_string = test_string;
98 callback.Run();
101 private:
102 TestContext* context_;
103 StrongBinding<TestService> binding_;
106 class TestClient {
107 public:
108 explicit TestClient(TestServicePtr service)
109 : service_(service.Pass()), quit_after_ack_(false) {}
111 void AckTest() {
112 if (quit_after_ack_)
113 base::MessageLoop::current()->Quit();
116 void Test(const std::string& test_string) {
117 quit_after_ack_ = true;
118 service_->Test(test_string,
119 base::Bind(&TestClient::AckTest, base::Unretained(this)));
122 private:
123 TestServicePtr service_;
124 bool quit_after_ack_;
125 DISALLOW_COPY_AND_ASSIGN(TestClient);
128 class TestContentHandler : public ContentHandler, public ApplicationDelegate {
129 public:
130 TestContentHandler(ApplicationConnection* connection,
131 InterfaceRequest<ContentHandler> request)
132 : binding_(this, request.Pass()) {}
134 // ContentHandler:
135 void StartApplication(InterfaceRequest<Application> application_request,
136 URLResponsePtr response) override {
137 apps_.push_back(new ApplicationImpl(this, application_request.Pass()));
140 private:
141 StrongBinding<ContentHandler> binding_;
142 ScopedVector<ApplicationImpl> apps_;
144 DISALLOW_COPY_AND_ASSIGN(TestContentHandler);
147 class TestApplicationLoader : public ApplicationLoader,
148 public ApplicationDelegate,
149 public InterfaceFactory<TestService>,
150 public InterfaceFactory<ContentHandler> {
151 public:
152 TestApplicationLoader()
153 : context_(nullptr), num_loads_(0), create_content_handler_(false) {}
155 ~TestApplicationLoader() override {
156 if (context_)
157 ++context_->num_loader_deletes;
158 test_app_.reset();
161 void set_create_content_handler(bool value) {
162 create_content_handler_ = true;
165 void set_context(TestContext* context) { context_ = context; }
166 int num_loads() const { return num_loads_; }
167 const GURL& last_requestor_url() const { return last_requestor_url_; }
169 private:
170 // ApplicationLoader implementation.
171 void Load(const GURL& url,
172 InterfaceRequest<Application> application_request) override {
173 ++num_loads_;
174 test_app_.reset(new ApplicationImpl(this, application_request.Pass()));
177 // ApplicationDelegate implementation.
178 bool ConfigureIncomingConnection(ApplicationConnection* connection) override {
179 connection->AddService<TestService>(this);
180 if (create_content_handler_)
181 connection->AddService<ContentHandler>(this);
182 last_requestor_url_ = GURL(connection->GetRemoteApplicationURL());
183 return true;
186 // InterfaceFactory<TestService> implementation.
187 void Create(ApplicationConnection* connection,
188 InterfaceRequest<TestService> request) override {
189 new TestServiceImpl(context_, request.Pass());
192 // InterfaceFactory<ContentHandler> implementation.
193 void Create(ApplicationConnection* connection,
194 InterfaceRequest<ContentHandler> request) override {
195 new TestContentHandler(connection, request.Pass());
198 scoped_ptr<ApplicationImpl> test_app_;
199 TestContext* context_;
200 int num_loads_;
201 GURL last_requestor_url_;
202 bool create_content_handler_;
204 DISALLOW_COPY_AND_ASSIGN(TestApplicationLoader);
207 class ClosingApplicationLoader : public ApplicationLoader {
208 private:
209 // ApplicationLoader implementation.
210 void Load(const GURL& url,
211 InterfaceRequest<Application> application_request) override {}
214 class TesterContext {
215 public:
216 explicit TesterContext(base::MessageLoop* loop)
217 : num_b_calls_(0),
218 num_c_calls_(0),
219 num_a_deletes_(0),
220 num_b_deletes_(0),
221 num_c_deletes_(0),
222 tester_called_quit_(false),
223 a_called_quit_(false),
224 loop_(loop) {}
226 void IncrementNumBCalls() {
227 base::AutoLock lock(lock_);
228 num_b_calls_++;
231 void IncrementNumCCalls() {
232 base::AutoLock lock(lock_);
233 num_c_calls_++;
236 void IncrementNumADeletes() {
237 base::AutoLock lock(lock_);
238 num_a_deletes_++;
241 void IncrementNumBDeletes() {
242 base::AutoLock lock(lock_);
243 num_b_deletes_++;
246 void IncrementNumCDeletes() {
247 base::AutoLock lock(lock_);
248 num_c_deletes_++;
251 void set_tester_called_quit() {
252 base::AutoLock lock(lock_);
253 tester_called_quit_ = true;
256 void set_a_called_quit() {
257 base::AutoLock lock(lock_);
258 a_called_quit_ = true;
261 int num_b_calls() {
262 base::AutoLock lock(lock_);
263 return num_b_calls_;
265 int num_c_calls() {
266 base::AutoLock lock(lock_);
267 return num_c_calls_;
269 int num_a_deletes() {
270 base::AutoLock lock(lock_);
271 return num_a_deletes_;
273 int num_b_deletes() {
274 base::AutoLock lock(lock_);
275 return num_b_deletes_;
277 int num_c_deletes() {
278 base::AutoLock lock(lock_);
279 return num_c_deletes_;
281 bool tester_called_quit() {
282 base::AutoLock lock(lock_);
283 return tester_called_quit_;
285 bool a_called_quit() {
286 base::AutoLock lock(lock_);
287 return a_called_quit_;
290 void QuitSoon() {
291 loop_->PostTask(FROM_HERE, base::MessageLoop::QuitWhenIdleClosure());
294 private:
295 // lock_ protects all members except for loop_ which must be unchanged for the
296 // lifetime of this class.
297 base::Lock lock_;
298 int num_b_calls_;
299 int num_c_calls_;
300 int num_a_deletes_;
301 int num_b_deletes_;
302 int num_c_deletes_;
303 bool tester_called_quit_;
304 bool a_called_quit_;
306 base::MessageLoop* loop_;
309 // Used to test that the requestor url will be correctly passed.
310 class TestAImpl : public TestA {
311 public:
312 TestAImpl(ApplicationImpl* app_impl,
313 TesterContext* test_context,
314 InterfaceRequest<TestA> request)
315 : test_context_(test_context), binding_(this, request.Pass()) {
316 mojo::URLRequestPtr request2(mojo::URLRequest::New());
317 request2->url = mojo::String::From(kTestBURLString);
318 connection_ = app_impl->ConnectToApplication(request2.Pass());
319 connection_->ConnectToService(&b_);
322 ~TestAImpl() override {
323 test_context_->IncrementNumADeletes();
324 if (base::MessageLoop::current()->is_running())
325 Quit();
328 private:
329 void CallB() override {
330 b_->B(base::Bind(&TestAImpl::Quit, base::Unretained(this)));
333 void CallCFromB() override {
334 b_->CallC(base::Bind(&TestAImpl::Quit, base::Unretained(this)));
337 void Quit() {
338 base::MessageLoop::current()->Quit();
339 test_context_->set_a_called_quit();
340 test_context_->QuitSoon();
343 scoped_ptr<ApplicationConnection> connection_;
344 TesterContext* test_context_;
345 TestBPtr b_;
346 StrongBinding<TestA> binding_;
349 class TestBImpl : public TestB {
350 public:
351 TestBImpl(ApplicationConnection* connection,
352 TesterContext* test_context,
353 InterfaceRequest<TestB> request)
354 : test_context_(test_context), binding_(this, request.Pass()) {
355 connection->ConnectToService(&c_);
358 ~TestBImpl() override {
359 test_context_->IncrementNumBDeletes();
360 if (base::MessageLoop::current()->is_running())
361 base::MessageLoop::current()->Quit();
362 test_context_->QuitSoon();
365 private:
366 void B(const Callback<void()>& callback) override {
367 test_context_->IncrementNumBCalls();
368 callback.Run();
371 void CallC(const Callback<void()>& callback) override {
372 test_context_->IncrementNumBCalls();
373 c_->C(callback);
376 TesterContext* test_context_;
377 TestCPtr c_;
378 StrongBinding<TestB> binding_;
381 class TestCImpl : public TestC {
382 public:
383 TestCImpl(ApplicationConnection* connection,
384 TesterContext* test_context,
385 InterfaceRequest<TestC> request)
386 : test_context_(test_context), binding_(this, request.Pass()) {}
388 ~TestCImpl() override { test_context_->IncrementNumCDeletes(); }
390 private:
391 void C(const Callback<void()>& callback) override {
392 test_context_->IncrementNumCCalls();
393 callback.Run();
396 TesterContext* test_context_;
397 StrongBinding<TestC> binding_;
400 class Tester : public ApplicationDelegate,
401 public ApplicationLoader,
402 public InterfaceFactory<TestA>,
403 public InterfaceFactory<TestB>,
404 public InterfaceFactory<TestC> {
405 public:
406 Tester(TesterContext* context, const std::string& requestor_url)
407 : context_(context), requestor_url_(requestor_url) {}
408 ~Tester() override {}
410 private:
411 void Load(const GURL& url,
412 InterfaceRequest<Application> application_request) override {
413 app_.reset(new ApplicationImpl(this, application_request.Pass()));
416 bool ConfigureIncomingConnection(ApplicationConnection* connection) override {
417 if (!requestor_url_.empty() &&
418 requestor_url_ != connection->GetRemoteApplicationURL()) {
419 context_->set_tester_called_quit();
420 context_->QuitSoon();
421 base::MessageLoop::current()->Quit();
422 return false;
424 // If we're coming from A, then add B, otherwise A.
425 if (connection->GetRemoteApplicationURL() == kTestAURLString)
426 connection->AddService<TestB>(this);
427 else
428 connection->AddService<TestA>(this);
429 return true;
432 bool ConfigureOutgoingConnection(ApplicationConnection* connection) override {
433 // If we're connecting to B, then add C.
434 if (connection->GetRemoteApplicationURL() == kTestBURLString)
435 connection->AddService<TestC>(this);
436 return true;
439 void Create(ApplicationConnection* connection,
440 InterfaceRequest<TestA> request) override {
441 a_bindings_.push_back(new TestAImpl(app_.get(), context_, request.Pass()));
444 void Create(ApplicationConnection* connection,
445 InterfaceRequest<TestB> request) override {
446 new TestBImpl(connection, context_, request.Pass());
449 void Create(ApplicationConnection* connection,
450 InterfaceRequest<TestC> request) override {
451 new TestCImpl(connection, context_, request.Pass());
454 TesterContext* context_;
455 scoped_ptr<ApplicationImpl> app_;
456 std::string requestor_url_;
457 ScopedVector<TestAImpl> a_bindings_;
460 class AMTestPackageManager : public TestPackageManager {
461 public:
462 AMTestPackageManager()
463 : create_test_fetcher_(false),
464 fetcher_url_("xxx"),
465 mime_type_(kTestMimeType) {}
466 ~AMTestPackageManager() override {}
468 void set_create_test_fetcher(bool create_test_fetcher) {
469 create_test_fetcher_ = create_test_fetcher;
472 void set_fetcher_url(const GURL& url) { fetcher_url_ = url; }
474 void set_mime_type(const std::string& mime_type) { mime_type_ = mime_type; }
476 // TestPackageManager:
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(AMTestPackageManager);
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 AMTestPackageManager)));
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 ConnectToService(application_manager_.get(), 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 AMTestPackageManager));
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 am.set_default_loader(scoped_ptr<ApplicationLoader>(default_loader));
574 am.SetLoaderForURL(scoped_ptr<ApplicationLoader>(url_loader1),
575 GURL("test:test1"));
576 am.SetLoaderForURL(scoped_ptr<ApplicationLoader>(url_loader2),
577 GURL("test:test1"));
579 EXPECT_EQ(3, context_.num_loader_deletes);
582 // Test for SetLoaderForURL() & set_default_loader().
583 TEST_F(ApplicationManagerTest, SetLoaders) {
584 TestApplicationLoader* default_loader = new TestApplicationLoader;
585 TestApplicationLoader* url_loader = new TestApplicationLoader;
586 application_manager_->set_default_loader(
587 scoped_ptr<ApplicationLoader>(default_loader));
588 application_manager_->SetLoaderForURL(
589 scoped_ptr<ApplicationLoader>(url_loader), GURL("test:test1"));
591 // test::test1 should go to url_loader.
592 TestServicePtr test_service;
593 ConnectToService(application_manager_.get(), GURL("test:test1"),
594 &test_service);
595 EXPECT_EQ(1, url_loader->num_loads());
596 EXPECT_EQ(0, default_loader->num_loads());
598 // http::test1 should go to default loader.
599 ConnectToService(application_manager_.get(), GURL("http:test1"),
600 &test_service);
601 EXPECT_EQ(1, url_loader->num_loads());
602 EXPECT_EQ(1, default_loader->num_loads());
605 // Confirm that the url of a service is correctly passed to another service that
606 // it loads.
607 TEST_F(ApplicationManagerTest, ACallB) {
608 // Any url can load a.
609 AddLoaderForURL(GURL(kTestAURLString), std::string());
611 // Only a can load b.
612 AddLoaderForURL(GURL(kTestBURLString), kTestAURLString);
614 TestAPtr a;
615 ConnectToService(application_manager_.get(), GURL(kTestAURLString), &a);
616 a->CallB();
617 loop_.Run();
618 EXPECT_EQ(1, tester_context_.num_b_calls());
619 EXPECT_TRUE(tester_context_.a_called_quit());
622 // A calls B which calls C.
623 TEST_F(ApplicationManagerTest, BCallC) {
624 // Any url can load a.
625 AddLoaderForURL(GURL(kTestAURLString), std::string());
627 // Only a can load b.
628 AddLoaderForURL(GURL(kTestBURLString), kTestAURLString);
630 TestAPtr a;
631 ConnectToService(application_manager_.get(), GURL(kTestAURLString), &a);
632 a->CallCFromB();
633 loop_.Run();
635 EXPECT_EQ(1, tester_context_.num_b_calls());
636 EXPECT_EQ(1, tester_context_.num_c_calls());
637 EXPECT_TRUE(tester_context_.a_called_quit());
640 // Confirm that a service impl will be deleted if the app that connected to
641 // it goes away.
642 TEST_F(ApplicationManagerTest, BDeleted) {
643 AddLoaderForURL(GURL(kTestAURLString), std::string());
644 AddLoaderForURL(GURL(kTestBURLString), std::string());
646 TestAPtr a;
647 ConnectToService(application_manager_.get(), GURL(kTestAURLString), &a);
649 a->CallB();
650 loop_.Run();
652 // Kills the a app.
653 application_manager_->SetLoaderForURL(scoped_ptr<ApplicationLoader>(),
654 GURL(kTestAURLString));
655 loop_.Run();
657 EXPECT_EQ(1, tester_context_.num_b_deletes());
660 // Confirm that the url of a service is correctly passed to another service that
661 // it loads, and that it can be rejected.
662 TEST_F(ApplicationManagerTest, ANoLoadB) {
663 // Any url can load a.
664 AddLoaderForURL(GURL(kTestAURLString), std::string());
666 // Only c can load b, so this will fail.
667 AddLoaderForURL(GURL(kTestBURLString), "test:TestC");
669 TestAPtr a;
670 ConnectToService(application_manager_.get(), GURL(kTestAURLString), &a);
671 a->CallB();
672 loop_.Run();
673 EXPECT_EQ(0, tester_context_.num_b_calls());
675 EXPECT_FALSE(tester_context_.a_called_quit());
676 EXPECT_TRUE(tester_context_.tester_called_quit());
679 TEST_F(ApplicationManagerTest, NoServiceNoLoad) {
680 AddLoaderForURL(GURL(kTestAURLString), std::string());
682 // There is no TestC service implementation registered with
683 // ApplicationManager, so this cannot succeed (but also shouldn't crash).
684 TestCPtr c;
685 ConnectToService(application_manager_.get(), GURL(kTestAURLString), &c);
686 c.set_connection_error_handler(
687 []() { base::MessageLoop::current()->QuitWhenIdle(); });
689 loop_.Run();
690 EXPECT_TRUE(c.encountered_error());
693 TEST_F(ApplicationManagerTest, TestEndApplicationClosure) {
694 ClosingApplicationLoader* loader = new ClosingApplicationLoader();
695 application_manager_->SetLoaderForURL(
696 scoped_ptr<ApplicationLoader>(loader), GURL("test:test"));
698 bool called = false;
699 scoped_ptr<ConnectToApplicationParams> params(new ConnectToApplicationParams);
700 params->SetURLInfo(GURL("test:test"));
701 params->set_filter(GetPermissiveCapabilityFilter());
702 params->set_on_application_end(
703 base::Bind(&QuitClosure, base::Unretained(&called)));
704 application_manager_->ConnectToApplication(params.Pass());
705 loop_.Run();
706 EXPECT_TRUE(called);
709 TEST(ApplicationManagerTest2, ContentHandlerConnectionGetsRequestorURL) {
710 const GURL content_handler_url("http://test.content.handler");
711 const GURL requestor_url("http://requestor.url");
712 TestContext test_context;
713 base::MessageLoop loop;
714 scoped_ptr<AMTestPackageManager> test_package_manager(
715 new AMTestPackageManager);
716 test_package_manager->set_create_test_fetcher(true);
717 test_package_manager->RegisterContentHandler(kTestMimeType,
718 content_handler_url);
719 ApplicationManager application_manager(test_package_manager.Pass());
720 application_manager.set_default_loader(nullptr);
722 TestApplicationLoader* loader = new TestApplicationLoader;
723 loader->set_context(&test_context);
724 application_manager.SetLoaderForURL(scoped_ptr<ApplicationLoader>(loader),
725 content_handler_url);
727 bool called = false;
728 scoped_ptr<ConnectToApplicationParams> params(new ConnectToApplicationParams);
729 params->set_originator_identity(Identity(requestor_url));
730 params->set_originator_filter(GetPermissiveCapabilityFilter());
731 params->SetURLInfo(GURL("test:test"));
732 params->set_filter(GetPermissiveCapabilityFilter());
733 params->set_on_application_end(
734 base::Bind(&QuitClosure, base::Unretained(&called)));
735 application_manager.ConnectToApplication(params.Pass());
736 loop.Run();
737 EXPECT_TRUE(called);
739 ASSERT_EQ(1, loader->num_loads());
740 EXPECT_EQ(requestor_url, loader->last_requestor_url());
743 TEST_F(ApplicationManagerTest, SameIdentityShouldNotCauseDuplicateLoad) {
744 // 1 because ApplicationManagerTest connects once at startup.
745 EXPECT_EQ(1, test_loader_->num_loads());
747 TestServicePtr test_service;
748 ConnectToService(application_manager_.get(),
749 GURL("http://www.example.org/abc?def"), &test_service);
750 EXPECT_EQ(2, test_loader_->num_loads());
752 // Exactly the same URL as above.
753 ConnectToService(application_manager_.get(),
754 GURL("http://www.example.org/abc?def"), &test_service);
755 EXPECT_EQ(2, test_loader_->num_loads());
757 // The same identity as the one above because only the query string is
758 // different.
759 ConnectToService(application_manager_.get(),
760 GURL("http://www.example.org/abc"), &test_service);
761 EXPECT_EQ(2, test_loader_->num_loads());
763 // A different identity because the path is different.
764 ConnectToService(application_manager_.get(),
765 GURL("http://www.example.org/another_path"), &test_service);
766 EXPECT_EQ(3, test_loader_->num_loads());
768 // A different identity because the domain is different.
769 ConnectToService(application_manager_.get(),
770 GURL("http://www.another_domain.org/abc"), &test_service);
771 EXPECT_EQ(4, test_loader_->num_loads());
774 TEST(ApplicationManagerTest2,
775 MultipleConnectionsToContentHandlerGetSameContentHandlerId) {
776 base::MessageLoop loop;
777 const GURL content_handler_url("http://test.content.handler");
778 const GURL requestor_url("http://requestor.url");
779 TestContext test_context;
780 scoped_ptr<AMTestPackageManager> test_package_manager(
781 new AMTestPackageManager);
782 test_package_manager->set_fetcher_url(GURL("test:test"));
783 test_package_manager->set_create_test_fetcher(true);
784 test_package_manager->RegisterContentHandler(kTestMimeType,
785 content_handler_url);
786 ApplicationManager application_manager(test_package_manager.Pass());
787 application_manager.set_default_loader(nullptr);
789 TestApplicationLoader* content_handler_loader = new TestApplicationLoader;
790 content_handler_loader->set_create_content_handler(true);
791 content_handler_loader->set_context(&test_context);
792 application_manager.SetLoaderForURL(
793 scoped_ptr<ApplicationLoader>(content_handler_loader),
794 content_handler_url);
796 uint32_t content_handler_id;
798 base::RunLoop run_loop;
799 scoped_ptr<ConnectToApplicationParams> params(
800 new ConnectToApplicationParams);
801 params->set_originator_identity(Identity(requestor_url));
802 params->set_originator_filter(GetPermissiveCapabilityFilter());
803 params->SetURLInfo(GURL("test:test"));
804 params->set_filter(GetPermissiveCapabilityFilter());
805 params->set_connect_callback([&content_handler_id, &run_loop](uint32_t t) {
806 content_handler_id = t;
807 run_loop.Quit();
809 application_manager.ConnectToApplication(params.Pass());
810 run_loop.Run();
811 EXPECT_NE(Shell::kInvalidContentHandlerID, content_handler_id);
814 uint32_t content_handler_id2;
816 base::RunLoop run_loop;
817 scoped_ptr<ConnectToApplicationParams> params(
818 new ConnectToApplicationParams);
819 params->set_originator_identity(Identity(requestor_url));
820 params->set_originator_filter(GetPermissiveCapabilityFilter());
821 params->SetURLInfo(GURL("test:test"));
822 params->set_filter(GetPermissiveCapabilityFilter());
823 params->set_connect_callback([&content_handler_id2, &run_loop](uint32_t t) {
824 content_handler_id2 = t;
825 run_loop.Quit();
827 application_manager.ConnectToApplication(params.Pass());
828 run_loop.Run();
829 EXPECT_NE(Shell::kInvalidContentHandlerID, content_handler_id2);
831 EXPECT_EQ(content_handler_id, content_handler_id2);
834 TEST(ApplicationManagerTest2, DifferedContentHandlersGetDifferentIDs) {
835 base::MessageLoop loop;
836 const GURL content_handler_url("http://test.content.handler");
837 const GURL requestor_url("http://requestor.url");
838 TestContext test_context;
839 AMTestPackageManager* test_package_manager = new AMTestPackageManager;
840 test_package_manager->set_fetcher_url(GURL("test:test"));
841 test_package_manager->set_create_test_fetcher(true);
842 test_package_manager->RegisterContentHandler(kTestMimeType,
843 content_handler_url);
844 ApplicationManager application_manager(make_scoped_ptr(test_package_manager));
845 application_manager.set_default_loader(nullptr);
847 TestApplicationLoader* content_handler_loader = new TestApplicationLoader;
848 content_handler_loader->set_create_content_handler(true);
849 content_handler_loader->set_context(&test_context);
850 application_manager.SetLoaderForURL(
851 scoped_ptr<ApplicationLoader>(content_handler_loader),
852 content_handler_url);
854 uint32_t content_handler_id;
856 base::RunLoop run_loop;
857 scoped_ptr<ConnectToApplicationParams> params(
858 new ConnectToApplicationParams);
859 params->set_originator_identity(Identity(requestor_url));
860 params->set_originator_filter(GetPermissiveCapabilityFilter());
861 params->SetURLInfo(GURL("test:test"));
862 params->set_filter(GetPermissiveCapabilityFilter());
863 params->set_connect_callback([&content_handler_id, &run_loop](uint32_t t) {
864 content_handler_id = t;
865 run_loop.Quit();
867 application_manager.ConnectToApplication(params.Pass());
868 run_loop.Run();
869 EXPECT_NE(Shell::kInvalidContentHandlerID, content_handler_id);
872 const std::string mime_type2("test/mime-type2");
873 const GURL content_handler_url2("http://test.content2.handler");
874 test_package_manager->set_fetcher_url(GURL("test2:test2"));
875 test_package_manager->set_mime_type(mime_type2);
876 test_package_manager->RegisterContentHandler(mime_type2,
877 content_handler_url2);
879 TestApplicationLoader* content_handler_loader2 = new TestApplicationLoader;
880 content_handler_loader->set_create_content_handler(true);
881 content_handler_loader->set_context(&test_context);
882 application_manager.SetLoaderForURL(
883 scoped_ptr<ApplicationLoader>(content_handler_loader2),
884 content_handler_url2);
886 uint32_t content_handler_id2;
888 base::RunLoop run_loop;
889 scoped_ptr<ConnectToApplicationParams> params(
890 new ConnectToApplicationParams);
891 params->set_originator_identity(Identity(requestor_url));
892 params->set_originator_filter(GetPermissiveCapabilityFilter());
893 params->SetURLInfo(GURL("test2:test2"));
894 params->set_filter(GetPermissiveCapabilityFilter());
895 params->set_connect_callback([&content_handler_id2, &run_loop](uint32_t t) {
896 content_handler_id2 = t;
897 run_loop.Quit();
899 application_manager.ConnectToApplication(params.Pass());
900 run_loop.Run();
901 EXPECT_NE(Shell::kInvalidContentHandlerID, content_handler_id2);
903 EXPECT_NE(content_handler_id, content_handler_id2);
906 TEST_F(ApplicationManagerTest,
907 ConnectWithNoContentHandlerGetsInvalidContentHandlerId) {
908 application_manager_->SetLoaderForURL(
909 scoped_ptr<ApplicationLoader>(new TestApplicationLoader),
910 GURL("test:test"));
912 uint32_t content_handler_id = 1u;
913 scoped_ptr<ConnectToApplicationParams> params(new ConnectToApplicationParams);
914 params->SetURLInfo(GURL("test:test"));
915 params->set_filter(GetPermissiveCapabilityFilter());
916 params->set_connect_callback(
917 [&content_handler_id](uint32_t t) { content_handler_id = t; });
918 application_manager_->ConnectToApplication(params.Pass());
919 EXPECT_EQ(0u, content_handler_id);
922 } // namespace
923 } // namespace shell
924 } // namespace mojo