11320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Copyright 2014 The Chromium Authors. All rights reserved.
21320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Use of this source code is governed by a BSD-style license that can be
31320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// found in the LICENSE file.
41320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/command_line.h"
61320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "content/public/browser/web_contents.h"
71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "content/public/common/content_switches.h"
81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "content/public/common/manifest.h"
91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "content/public/test/browser_test_utils.h"
101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "content/public/test/content_browser_test.h"
111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "content/public/test/content_browser_test_utils.h"
121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "content/public/test/test_navigation_observer.h"
131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "content/shell/browser/shell.h"
141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "net/test/embedded_test_server/embedded_test_server.h"
151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace content {
171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass ManifestBrowserTest : public ContentBrowserTest  {
191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci protected:
201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ManifestBrowserTest() {}
211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual ~ManifestBrowserTest() {}
221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void GetManifestAndWait() {
241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    shell()->web_contents()->GetManifest(
251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        base::Bind(&ManifestBrowserTest::OnGetManifest,
261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                   base::Unretained(this)));
271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    message_loop_runner_ = new MessageLoopRunner();
291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    message_loop_runner_->Run();
301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void OnGetManifest(const Manifest& manifest) {
331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    manifest_ = manifest;
341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    message_loop_runner_->Quit();
351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const Manifest& manifest() const {
381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return manifest_;
391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci private:
421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_refptr<MessageLoopRunner> message_loop_runner_;
431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  Manifest manifest_;
441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DISALLOW_COPY_AND_ASSIGN(ManifestBrowserTest);
461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci};
471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// If a page has no manifest, requesting a manifest should return the empty
491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// manifest.
501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciIN_PROC_BROWSER_TEST_F(ManifestBrowserTest, NoManifest) {
511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  GURL test_url = GetTestUrl("manifest", "no-manifest.html");
521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TestNavigationObserver navigation_observer(shell()->web_contents(), 1);
541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  shell()->LoadURL(test_url);
551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  navigation_observer.Wait();
561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  GetManifestAndWait();
581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(manifest().IsEmpty());
591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// If a page manifest points to a 404 URL, requesting the manifest should return
621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// the empty manifest.
631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciIN_PROC_BROWSER_TEST_F(ManifestBrowserTest, 404Manifest) {
641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  GURL test_url = GetTestUrl("manifest", "404-manifest.html");
651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TestNavigationObserver navigation_observer(shell()->web_contents(), 1);
671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  shell()->LoadURL(test_url);
681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  navigation_observer.Wait();
691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  GetManifestAndWait();
711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(manifest().IsEmpty());
721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// If a page has an empty manifest, requesting the manifest should return the
751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// empty manifest.
761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciIN_PROC_BROWSER_TEST_F(ManifestBrowserTest, EmptyManifest) {
771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  GURL test_url = GetTestUrl("manifest", "empty-manifest.html");
781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TestNavigationObserver navigation_observer(shell()->web_contents(), 1);
801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  shell()->LoadURL(test_url);
811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  navigation_observer.Wait();
821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  GetManifestAndWait();
841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(manifest().IsEmpty());
851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// If a page's manifest can't be parsed correctly, requesting the manifest
881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// should return an empty manifest.
891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciIN_PROC_BROWSER_TEST_F(ManifestBrowserTest, ParseErrorManifest) {
901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  GURL test_url = GetTestUrl("manifest", "parse-error-manifest.html");
911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TestNavigationObserver navigation_observer(shell()->web_contents(), 1);
931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  shell()->LoadURL(test_url);
941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  navigation_observer.Wait();
951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  GetManifestAndWait();
971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(manifest().IsEmpty());
981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// If a page has a manifest that can be fetched and parsed, requesting the
1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// manifest should return a properly filled manifest.
1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciIN_PROC_BROWSER_TEST_F(ManifestBrowserTest, DummyManifest) {
1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  GURL test_url = GetTestUrl("manifest", "dummy-manifest.html");
1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TestNavigationObserver navigation_observer(shell()->web_contents(), 1);
1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  shell()->LoadURL(test_url);
1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  navigation_observer.Wait();
1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  GetManifestAndWait();
1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_FALSE(manifest().IsEmpty());
1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// If a page changes manifest during its life-time, requesting the manifest
1141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// should return the current manifest.
1151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciIN_PROC_BROWSER_TEST_F(ManifestBrowserTest, DynamicManifest) {
1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  GURL test_url = GetTestUrl("manifest", "dynamic-manifest.html");
1171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TestNavigationObserver navigation_observer(shell()->web_contents(), 1);
1191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  shell()->LoadURL(test_url);
1201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  navigation_observer.Wait();
1211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  {
1231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    GetManifestAndWait();
1241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_TRUE(manifest().IsEmpty());
1251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  {
1281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    std::string manifest_url =
1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        GetTestUrl("manifest", "dummy-manifest.json").spec();
1301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ASSERT_TRUE(content::ExecuteScript(
1311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        shell()->web_contents(), "setManifestTo('" + manifest_url + "')"));
1321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    GetManifestAndWait();
1341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_FALSE(manifest().IsEmpty());
1351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  {
1381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    std::string manifest_url =
1391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        GetTestUrl("manifest", "empty-manifest.json").spec();
1401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ASSERT_TRUE(content::ExecuteScript(
1411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        shell()->web_contents(), "setManifestTo('" + manifest_url + "')"));
1421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    GetManifestAndWait();
1441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_TRUE(manifest().IsEmpty());
1451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// If a page's manifest lives in a different origin, it should follow the CORS
1491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// rules and requesting the manifest should return an empty manifest (unless the
1501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// response contains CORS headers).
1511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciIN_PROC_BROWSER_TEST_F(ManifestBrowserTest, CORSManifest) {
1521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<net::test_server::EmbeddedTestServer> cors_embedded_test_server(
1531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new net::test_server::EmbeddedTestServer);
1541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
1561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_TRUE(cors_embedded_test_server->InitializeAndWaitUntilReady());
1571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_NE(embedded_test_server()->port(), cors_embedded_test_server->port());
1581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  GURL test_url =
1601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      embedded_test_server()->GetURL("/manifest/dynamic-manifest.html");
1611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TestNavigationObserver navigation_observer(shell()->web_contents(), 1);
1631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  shell()->LoadURL(test_url);
1641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  navigation_observer.Wait();
1651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::string manifest_url =
1671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      cors_embedded_test_server->GetURL("/manifest/dummy-manifest.json").spec();
1681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_TRUE(content::ExecuteScript(shell()->web_contents(),
1691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                     "setManifestTo('" + manifest_url + "')"));
1701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  GetManifestAndWait();
1721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(manifest().IsEmpty());
1731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// If a page's manifest is in an unsecure origin while the page is in a secure
1761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// origin, requesting the manifest should return the empty manifest.
1771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciIN_PROC_BROWSER_TEST_F(ManifestBrowserTest, MixedContentManifest) {
1781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<net::SpawnedTestServer> https_server(new net::SpawnedTestServer(
1791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      net::SpawnedTestServer::TYPE_HTTPS,
1801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      net::BaseTestServer::SSLOptions(net::BaseTestServer::SSLOptions::CERT_OK),
1811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::FilePath(FILE_PATH_LITERAL("content/test/data"))));
1821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
1841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_TRUE(https_server->Start());
1851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  GURL test_url =
1871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      embedded_test_server()->GetURL("/manifest/dynamic-manifest.html");
1881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TestNavigationObserver navigation_observer(shell()->web_contents(), 1);
1901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  shell()->LoadURL(test_url);
1911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  navigation_observer.Wait();
1921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::string manifest_url =
1941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      https_server->GetURL("/manifest/dummy-manifest.json").spec();
1951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_TRUE(content::ExecuteScript(shell()->web_contents(),
1961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                     "setManifestTo('" + manifest_url + "')"));
1971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  GetManifestAndWait();
1991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(manifest().IsEmpty());
2001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} // namespace content
203