1 // Copyright 2015 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/macros.h"
7 #include "base/memory/scoped_ptr.h"
8 #include "base/message_loop/message_loop.h"
9 #include "base/path_service.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/common/weak_binding_set.h"
17 #include "mojo/fetcher/about_fetcher.h"
18 #include "mojo/package_manager/package_manager_impl.h"
19 #include "mojo/runner/context.h"
20 #include "mojo/shell/application_loader.h"
21 #include "mojo/shell/application_manager.h"
22 #include "mojo/util/filename_util.h"
23 #include "testing/gtest/include/gtest/gtest.h"
29 class TestContentHandler
: public ApplicationDelegate
,
30 public InterfaceFactory
<ContentHandler
>,
31 public ContentHandler
{
33 TestContentHandler() : response_number_(0) {}
34 ~TestContentHandler() override
{}
36 size_t response_number() const { return response_number_
; }
37 const URLResponse
* latest_response() const { return latest_response_
.get(); }
40 // Overridden from ApplicationDelegate:
41 void Initialize(ApplicationImpl
* app
) override
{}
42 bool ConfigureIncomingConnection(ApplicationConnection
* connection
) override
{
43 connection
->AddService
<ContentHandler
>(this);
47 // Overridden from InterfaceFactory<ContentHandler>:
48 void Create(ApplicationConnection
* connection
,
49 InterfaceRequest
<ContentHandler
> request
) override
{
50 bindings_
.AddBinding(this, request
.Pass());
53 // Overridden from ContentHandler:
54 void StartApplication(InterfaceRequest
<Application
> application
,
55 URLResponsePtr response
) override
{
57 latest_response_
= response
.Pass();
59 // Drop |application| request. This results in the application manager
60 // dropping the ServiceProvider interface request provided by the client
61 // who made the ConnectToApplication() call. Therefore the client could
62 // listen for connection error of the ServiceProvider interface to learn
63 // that StartApplication() has been called.
66 size_t response_number_
;
67 URLResponsePtr latest_response_
;
68 WeakBindingSet
<ContentHandler
> bindings_
;
70 DISALLOW_COPY_AND_ASSIGN(TestContentHandler
);
73 class TestLoader
: public shell::ApplicationLoader
{
75 explicit TestLoader(ApplicationDelegate
* delegate
) : delegate_(delegate
) {}
76 ~TestLoader() override
{}
79 // Overridden from ApplicationLoader:
80 void Load(const GURL
& url
, InterfaceRequest
<Application
> request
) override
{
81 app_
.reset(new ApplicationImpl(delegate_
, request
.Pass()));
84 ApplicationDelegate
* delegate_
;
85 scoped_ptr
<ApplicationImpl
> app_
;
87 DISALLOW_COPY_AND_ASSIGN(TestLoader
);
90 class AboutFetcherTest
: public testing::Test
{
93 ~AboutFetcherTest() override
{}
96 const TestContentHandler
* html_content_handler() const {
97 return &html_content_handler_
;
100 void ConnectAndWait(const std::string
& url
) {
101 base::RunLoop run_loop
;
103 ServiceProviderPtr service_provider
;
104 InterfaceRequest
<ServiceProvider
> service_provider_request
=
105 GetProxy(&service_provider
);
106 // This connection error handler will be called when:
107 // - TestContentHandler::StartApplication() has been called (please see
108 // comments in that method); or
109 // - the application manager fails to fetch the requested URL.
110 service_provider
.set_connection_error_handler(
111 [&run_loop
]() { run_loop
.Quit(); });
113 URLRequestPtr
request(URLRequest::New());
116 scoped_ptr
<shell::ConnectToApplicationParams
> params(
117 new shell::ConnectToApplicationParams
);
118 params
->SetURLInfo(request
.Pass());
119 params
->set_services(service_provider_request
.Pass());
120 application_manager_
->ConnectToApplication(params
.Pass());
125 // Overridden from testing::Test:
126 void SetUp() override
{
127 runner::Context::EnsureEmbedderIsInitialized();
128 base::FilePath shell_dir
;
129 PathService::Get(base::DIR_MODULE
, &shell_dir
);
130 scoped_ptr
<package_manager::PackageManagerImpl
> package_manager(
131 new package_manager::PackageManagerImpl(shell_dir
));
132 package_manager
->RegisterContentHandler(
133 "text/html", GURL("test:html_content_handler"));
134 application_manager_
.reset(
135 new shell::ApplicationManager(package_manager
.Pass()));
136 application_manager_
->SetLoaderForURL(
137 make_scoped_ptr(new TestLoader(&html_content_handler_
)),
138 GURL("test:html_content_handler"));
141 void TearDown() override
{ application_manager_
.reset(); }
144 base::ShadowingAtExitManager at_exit_
;
145 TestContentHandler html_content_handler_
;
146 base::MessageLoop loop_
;
147 scoped_ptr
<shell::ApplicationManager
> application_manager_
;
149 DISALLOW_COPY_AND_ASSIGN(AboutFetcherTest
);
152 TEST_F(AboutFetcherTest
, AboutBlank
) {
153 ConnectAndWait("about:blank");
155 ASSERT_EQ(1u, html_content_handler()->response_number());
157 const URLResponse
* response
= html_content_handler()->latest_response();
158 EXPECT_EQ("about:blank", response
->url
);
159 EXPECT_EQ(200u, response
->status_code
);
160 EXPECT_EQ("text/html", response
->mime_type
);
161 EXPECT_FALSE(response
->body
.is_valid());
164 TEST_F(AboutFetcherTest
, UnrecognizedURL
) {
165 ConnectAndWait("about:some_unrecognized_url");
167 ASSERT_EQ(1u, html_content_handler()->response_number());
169 const URLResponse
* response
= html_content_handler()->latest_response();
170 EXPECT_EQ("about:some_unrecognized_url", response
->url
);
171 EXPECT_EQ(404u, response
->status_code
);
172 EXPECT_EQ("text/html", response
->mime_type
);
173 EXPECT_FALSE(response
->body
.is_valid());
177 } // namespace fetcher