Supervised user whitelists: Cleanup
[chromium-blink-merge.git] / content / browser / manifest / manifest_browsertest.cc
blob043b5926d40ceb281db1a0965669592f3e41c620
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/command_line.h"
6 #include "base/path_service.h"
7 #include "content/public/browser/web_contents.h"
8 #include "content/public/common/content_switches.h"
9 #include "content/public/common/manifest.h"
10 #include "content/public/test/browser_test_utils.h"
11 #include "content/public/test/content_browser_test.h"
12 #include "content/public/test/content_browser_test_utils.h"
13 #include "content/public/test/test_navigation_observer.h"
14 #include "content/shell/browser/shell.h"
15 #include "net/test/embedded_test_server/embedded_test_server.h"
17 namespace content {
19 class ManifestBrowserTest;
21 // Mock of a WebContentsDelegate that catches messages sent to the console.
22 class MockWebContentsDelegate : public WebContentsDelegate {
23 public:
24 MockWebContentsDelegate(WebContents* web_contents, ManifestBrowserTest* test)
25 : web_contents_(web_contents),
26 test_(test) {
29 bool AddMessageToConsole(WebContents* source,
30 int32 level,
31 const base::string16& message,
32 int32 line_no,
33 const base::string16& source_id) override;
35 private:
36 WebContents* web_contents_;
37 ManifestBrowserTest* test_;
40 class ManifestBrowserTest : public ContentBrowserTest {
41 protected:
42 friend MockWebContentsDelegate;
44 ManifestBrowserTest()
45 : console_error_count_(0) {
46 cors_embedded_test_server_.reset(new net::test_server::EmbeddedTestServer);
47 base::FilePath test_data_dir;
48 CHECK(PathService::Get(base::DIR_SOURCE_ROOT, &test_data_dir));
49 cors_embedded_test_server_->ServeFilesFromDirectory(
50 test_data_dir.AppendASCII("content/test/data/"));
53 ~ManifestBrowserTest() override {}
55 void SetUpOnMainThread() override {
56 ContentBrowserTest::SetUpOnMainThread();
57 DCHECK(shell()->web_contents());
59 mock_web_contents_delegate_.reset(
60 new MockWebContentsDelegate(shell()->web_contents(), this));
61 shell()->web_contents()->SetDelegate(mock_web_contents_delegate_.get());
64 void GetManifestAndWait() {
65 shell()->web_contents()->GetManifest(
66 base::Bind(&ManifestBrowserTest::OnGetManifest,
67 base::Unretained(this)));
69 message_loop_runner_ = new MessageLoopRunner();
70 message_loop_runner_->Run();
73 void OnGetManifest(const Manifest& manifest) {
74 manifest_ = manifest;
75 message_loop_runner_->Quit();
78 const Manifest& manifest() const {
79 return manifest_;
82 unsigned int console_error_count() const {
83 return console_error_count_;
86 void OnReceivedConsoleError() {
87 console_error_count_++;
90 net::test_server::EmbeddedTestServer* cors_embedded_test_server() const {
91 return cors_embedded_test_server_.get();
94 private:
95 scoped_refptr<MessageLoopRunner> message_loop_runner_;
96 scoped_ptr<MockWebContentsDelegate> mock_web_contents_delegate_;
97 scoped_ptr<net::test_server::EmbeddedTestServer> cors_embedded_test_server_;
98 Manifest manifest_;
99 int console_error_count_;
101 DISALLOW_COPY_AND_ASSIGN(ManifestBrowserTest);
104 // The implementation of AddMessageToConsole isn't inlined because it needs
105 // to know about |test_|.
106 bool MockWebContentsDelegate::AddMessageToConsole(
107 WebContents* source,
108 int32 level,
109 const base::string16& message,
110 int32 line_no,
111 const base::string16& source_id) {
112 DCHECK(source == web_contents_);
114 if (level == logging::LOG_ERROR)
115 test_->OnReceivedConsoleError();
116 return false;
119 // If a page has no manifest, requesting a manifest should return the empty
120 // manifest.
121 IN_PROC_BROWSER_TEST_F(ManifestBrowserTest, NoManifest) {
122 GURL test_url = GetTestUrl("manifest", "no-manifest.html");
124 TestNavigationObserver navigation_observer(shell()->web_contents(), 1);
125 shell()->LoadURL(test_url);
126 navigation_observer.Wait();
128 GetManifestAndWait();
129 EXPECT_TRUE(manifest().IsEmpty());
130 EXPECT_EQ(0u, console_error_count());
133 // If a page manifest points to a 404 URL, requesting the manifest should return
134 // the empty manifest.
135 IN_PROC_BROWSER_TEST_F(ManifestBrowserTest, 404Manifest) {
136 GURL test_url = GetTestUrl("manifest", "404-manifest.html");
138 TestNavigationObserver navigation_observer(shell()->web_contents(), 1);
139 shell()->LoadURL(test_url);
140 navigation_observer.Wait();
142 GetManifestAndWait();
143 EXPECT_TRUE(manifest().IsEmpty());
144 EXPECT_EQ(0u, console_error_count());
147 // If a page has an empty manifest, requesting the manifest should return the
148 // empty manifest.
149 IN_PROC_BROWSER_TEST_F(ManifestBrowserTest, EmptyManifest) {
150 GURL test_url = GetTestUrl("manifest", "empty-manifest.html");
152 TestNavigationObserver navigation_observer(shell()->web_contents(), 1);
153 shell()->LoadURL(test_url);
154 navigation_observer.Wait();
156 GetManifestAndWait();
157 EXPECT_TRUE(manifest().IsEmpty());
158 EXPECT_EQ(0u, console_error_count());
161 // If a page's manifest can't be parsed correctly, requesting the manifest
162 // should return an empty manifest.
163 IN_PROC_BROWSER_TEST_F(ManifestBrowserTest, ParseErrorManifest) {
164 GURL test_url = GetTestUrl("manifest", "parse-error-manifest.html");
166 TestNavigationObserver navigation_observer(shell()->web_contents(), 1);
167 shell()->LoadURL(test_url);
168 navigation_observer.Wait();
170 GetManifestAndWait();
171 EXPECT_TRUE(manifest().IsEmpty());
172 EXPECT_EQ(1u, console_error_count());
175 // If a page has a manifest that can be fetched and parsed, requesting the
176 // manifest should return a properly filled manifest.
177 IN_PROC_BROWSER_TEST_F(ManifestBrowserTest, DummyManifest) {
178 GURL test_url = GetTestUrl("manifest", "dummy-manifest.html");
180 TestNavigationObserver navigation_observer(shell()->web_contents(), 1);
181 shell()->LoadURL(test_url);
182 navigation_observer.Wait();
184 GetManifestAndWait();
185 EXPECT_FALSE(manifest().IsEmpty());
186 EXPECT_EQ(0u, console_error_count());
189 // If a page changes manifest during its life-time, requesting the manifest
190 // should return the current manifest.
191 IN_PROC_BROWSER_TEST_F(ManifestBrowserTest, DynamicManifest) {
192 GURL test_url = GetTestUrl("manifest", "dynamic-manifest.html");
194 TestNavigationObserver navigation_observer(shell()->web_contents(), 1);
195 shell()->LoadURL(test_url);
196 navigation_observer.Wait();
199 GetManifestAndWait();
200 EXPECT_TRUE(manifest().IsEmpty());
204 std::string manifest_url =
205 GetTestUrl("manifest", "dummy-manifest.json").spec();
206 ASSERT_TRUE(content::ExecuteScript(
207 shell()->web_contents(), "setManifestTo('" + manifest_url + "')"));
209 GetManifestAndWait();
210 EXPECT_FALSE(manifest().IsEmpty());
214 std::string manifest_url =
215 GetTestUrl("manifest", "empty-manifest.json").spec();
216 ASSERT_TRUE(content::ExecuteScript(
217 shell()->web_contents(), "setManifestTo('" + manifest_url + "')"));
219 GetManifestAndWait();
220 EXPECT_TRUE(manifest().IsEmpty());
223 EXPECT_EQ(0u, console_error_count());
226 // If a page's manifest lives in a different origin, it should follow the CORS
227 // rules and requesting the manifest should return an empty manifest (unless the
228 // response contains CORS headers).
229 IN_PROC_BROWSER_TEST_F(ManifestBrowserTest, CORSManifest) {
230 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
231 ASSERT_TRUE(cors_embedded_test_server()->InitializeAndWaitUntilReady());
232 ASSERT_NE(embedded_test_server()->port(),
233 cors_embedded_test_server()->port());
235 GURL test_url =
236 embedded_test_server()->GetURL("/manifest/dynamic-manifest.html");
238 TestNavigationObserver navigation_observer(shell()->web_contents(), 1);
239 shell()->LoadURL(test_url);
240 navigation_observer.Wait();
242 std::string manifest_url = cors_embedded_test_server()->GetURL(
243 "/manifest/dummy-manifest.json").spec();
244 ASSERT_TRUE(content::ExecuteScript(shell()->web_contents(),
245 "setManifestTo('" + manifest_url + "')"));
247 GetManifestAndWait();
248 EXPECT_TRUE(manifest().IsEmpty());
250 EXPECT_EQ(0u, console_error_count());
252 // The purpose of this second load is to make sure the first load is fully
253 // finished. The first load will fail because of Access Control error but the
254 // underlying Blink loader will continue fetching the file. There is no
255 // reliable way to know when the fetch is finished from the browser test
256 // except by fetching the same file from same origin, making it succeed when
257 // it is actually fully loaded.
258 manifest_url =
259 embedded_test_server()->GetURL("/manifest/dummy-manifest.json").spec();
260 ASSERT_TRUE(content::ExecuteScript(shell()->web_contents(),
261 "setManifestTo('" + manifest_url + "')"));
262 GetManifestAndWait();
265 // If a page's manifest lives in a different origin, it should be accessible if
266 // it has valid access controls headers.
267 IN_PROC_BROWSER_TEST_F(ManifestBrowserTest, CORSManifestWithAcessControls) {
268 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
269 ASSERT_TRUE(cors_embedded_test_server()->InitializeAndWaitUntilReady());
270 ASSERT_NE(embedded_test_server()->port(),
271 cors_embedded_test_server()->port());
273 GURL test_url =
274 embedded_test_server()->GetURL("/manifest/dynamic-manifest.html");
276 TestNavigationObserver navigation_observer(shell()->web_contents(), 1);
277 shell()->LoadURL(test_url);
278 navigation_observer.Wait();
280 std::string manifest_url = cors_embedded_test_server()->GetURL(
281 "/manifest/manifest-cors.json").spec();
282 ASSERT_TRUE(content::ExecuteScript(shell()->web_contents(),
283 "setManifestTo('" + manifest_url + "')"));
285 GetManifestAndWait();
286 EXPECT_FALSE(manifest().IsEmpty());
288 EXPECT_EQ(0u, console_error_count());
291 // If a page's manifest is in an insecure origin while the page is in a secure
292 // origin, requesting the manifest should return the empty manifest.
293 IN_PROC_BROWSER_TEST_F(ManifestBrowserTest, MixedContentManifest) {
294 scoped_ptr<net::SpawnedTestServer> https_server(new net::SpawnedTestServer(
295 net::SpawnedTestServer::TYPE_HTTPS,
296 net::BaseTestServer::SSLOptions(net::BaseTestServer::SSLOptions::CERT_OK),
297 base::FilePath(FILE_PATH_LITERAL("content/test/data"))));
299 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
300 ASSERT_TRUE(https_server->Start());
302 GURL test_url =
303 embedded_test_server()->GetURL("/manifest/dynamic-manifest.html");
305 TestNavigationObserver navigation_observer(shell()->web_contents(), 1);
306 shell()->LoadURL(test_url);
307 navigation_observer.Wait();
309 std::string manifest_url =
310 https_server->GetURL("/manifest/dummy-manifest.json").spec();
311 ASSERT_TRUE(content::ExecuteScript(shell()->web_contents(),
312 "setManifestTo('" + manifest_url + "')"));
314 GetManifestAndWait();
315 EXPECT_TRUE(manifest().IsEmpty());
317 EXPECT_EQ(0u, console_error_count());
320 // If a page's manifest has some parsing errors, they should show up in the
321 // developer console.
322 IN_PROC_BROWSER_TEST_F(ManifestBrowserTest, ParsingErrorsManifest) {
323 GURL test_url = GetTestUrl("manifest", "parsing-errors.html");
325 TestNavigationObserver navigation_observer(shell()->web_contents(), 1);
326 shell()->LoadURL(test_url);
327 navigation_observer.Wait();
329 GetManifestAndWait();
330 EXPECT_TRUE(manifest().IsEmpty());
331 EXPECT_EQ(6u, console_error_count());
334 // If a page has a manifest and the page is navigated to a page without a
335 // manifest, the page's manifest should be updated.
336 IN_PROC_BROWSER_TEST_F(ManifestBrowserTest, Navigation) {
337 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
339 GURL test_url =
340 embedded_test_server()->GetURL("/manifest/dummy-manifest.html");
342 TestNavigationObserver navigation_observer(shell()->web_contents(), 1);
343 shell()->LoadURL(test_url);
344 navigation_observer.Wait();
346 GetManifestAndWait();
347 EXPECT_FALSE(manifest().IsEmpty());
348 EXPECT_EQ(0u, console_error_count());
352 GURL test_url =
353 embedded_test_server()->GetURL("/manifest/no-manifest.html");
355 TestNavigationObserver navigation_observer(shell()->web_contents(), 1);
356 shell()->LoadURL(test_url);
357 navigation_observer.Wait();
359 GetManifestAndWait();
360 EXPECT_TRUE(manifest().IsEmpty());
361 EXPECT_EQ(0u, console_error_count());
365 // If a page has a manifest and the page is navigated using pushState (ie. same
366 // page), it should keep its manifest state.
367 IN_PROC_BROWSER_TEST_F(ManifestBrowserTest, PushStateNavigation) {
368 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
369 GURL test_url =
370 embedded_test_server()->GetURL("/manifest/dummy-manifest.html");
373 TestNavigationObserver navigation_observer(shell()->web_contents(), 1);
374 shell()->LoadURL(test_url);
375 navigation_observer.Wait();
379 TestNavigationObserver navigation_observer(shell()->web_contents(), 1);
380 ASSERT_TRUE(content::ExecuteScript(
381 shell()->web_contents(),
382 "history.pushState({foo: \"bar\"}, 'page', 'page.html');"));
383 navigation_observer.Wait();
386 GetManifestAndWait();
387 EXPECT_FALSE(manifest().IsEmpty());
388 EXPECT_EQ(0u, console_error_count());
391 // If a page has a manifest and is navigated using an anchor (ie. same page), it
392 // should keep its manifest state.
393 IN_PROC_BROWSER_TEST_F(ManifestBrowserTest, AnchorNavigation) {
394 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
395 GURL test_url =
396 embedded_test_server()->GetURL("/manifest/dummy-manifest.html");
399 TestNavigationObserver navigation_observer(shell()->web_contents(), 1);
400 shell()->LoadURL(test_url);
401 navigation_observer.Wait();
405 TestNavigationObserver navigation_observer(shell()->web_contents(), 1);
406 ASSERT_TRUE(content::ExecuteScript(
407 shell()->web_contents(),
408 "var a = document.createElement('a'); a.href='#foo';"
409 "document.body.appendChild(a); a.click();"));
410 navigation_observer.Wait();
413 GetManifestAndWait();
414 EXPECT_FALSE(manifest().IsEmpty());
415 EXPECT_EQ(0u, console_error_count());
418 } // namespace content