// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "build/build_config.h"
#include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/extensions/bookmark_app_helper.h"
#include "chrome/browser/extensions/bookmark_app_navigation_browsertest.h"
#include "chrome/browser/extensions/bookmark_app_navigation_throttle_utils.h"
#include "chrome/browser/extensions/launch_util.h"
#include "chrome/browser/prefs/session_startup_pref.h"
#include "chrome/browser/prerender/prerender_manager.h"
#include "chrome/browser/renderer_context_menu/render_view_context_menu_test_util.h"
#include "chrome/browser/ui/browser_commands.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/extensions/app_launch_params.h"
#include "chrome/browser/ui/extensions/application_launch.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/browser/web_applications/extensions/web_app_extension_helpers.h"
#include "chrome/common/chrome_features.h"
#include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/notification_details.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/common/context_menu_params.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/test_frame_navigation_observer.h"
#include "content/public/test/test_navigation_observer.h"
#include "content/public/test/test_utils.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/notification_types.h"
#include "extensions/common/constants.h"
#include "net/base/escape.h"
#include "net/http/http_request_headers.h"
#include "net/url_request/url_fetcher.h"
#include "services/network/public/cpp/resource_request_body.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace extensions {
namespace test {

enum class StartIn {
  BROWSER,
  APP,
};

enum class WindowAccessResult {
  CAN_ACCESS,
  CANNOT_ACCESS,
  // Used for when there was an unexpected issue when accessing the other window
  // e.g. there is no other window, or the other window's URL does not match the
  // expected URL.
  OTHER,
};

namespace {

const char kTextPlainEncType[] = "text/plain";

const char kQueryParam[] = "test=";
const char kQueryParamName[] = "test";

// On macOS the Meta key is used as a modifier instead of Control.
#if defined(OS_MACOSX)
constexpr int kCtrlOrMeta = blink::WebInputEvent::kMetaKey;
#else
constexpr int kCtrlOrMeta = blink::WebInputEvent::kControlKey;
#endif

// Subclass of TestNavigationObserver that saves extra information about the
// navigation and watches all navigations to |target_url|.
class BookmarkAppNavigationObserver : public content::TestNavigationObserver {
 public:
  // Creates an observer that watches navigations to |target_url| on all
  // existing and newly added WebContents.
  explicit BookmarkAppNavigationObserver(const GURL& target_url)
      : content::TestNavigationObserver(target_url),
        last_navigation_is_post_(false) {
    WatchExistingWebContents();
    StartWatchingNewWebContents();
  }

  bool last_navigation_is_post() const { return last_navigation_is_post_; }

  const net::HttpRequestHeaders& last_request_headers() const {
    return last_request_headers_;
  }

  const scoped_refptr<network::ResourceRequestBody>&
  last_resource_request_body() const {
    return last_resource_request_body_;
  }

 private:
  void OnDidFinishNavigation(
      content::NavigationHandle* navigation_handle) override {
    last_navigation_is_post_ = navigation_handle->IsPost();
    last_request_headers_ = navigation_handle->GetRequestHeaders();
    last_resource_request_body_ = navigation_handle->GetResourceRequestBody();
    content::TestNavigationObserver::OnDidFinishNavigation(navigation_handle);
  }

  // True if the last navigation was a post.
  bool last_navigation_is_post_;

  // The request headers of the last navigation.
  net::HttpRequestHeaders last_request_headers_;

  // The request body of the last navigation if it was a post request.
  scoped_refptr<network::ResourceRequestBody> last_resource_request_body_;
};

void ExpectNavigationResultHistogramEquals(
    const base::HistogramTester& histogram_tester,
    const std::vector<std::pair<BookmarkAppNavigationThrottleResult,
                                base::HistogramBase::Count>>& expected_counts) {
  std::vector<base::Bucket> expected_bucket_counts;
  for (const auto& pair : expected_counts) {
    expected_bucket_counts.push_back(base::Bucket(
        static_cast<base::HistogramBase::Sample>(pair.first), pair.second));
  }

  EXPECT_THAT(
      histogram_tester.GetAllSamples("Extensions.BookmarkApp.NavigationResult"),
      testing::UnorderedElementsAreArray(expected_bucket_counts));
}

// When an app is launched, whether it's in response to a navigation or click
// in a launch surface e.g. App Shelf, the first navigation in the app is
// an AUTO_BOOKMARK navigation.
std::pair<BookmarkAppNavigationThrottleResult, base::HistogramBase::Count>
GetAppLaunchedEntry() {
  return {BookmarkAppNavigationThrottleResult::kProceedTransitionAutoBookmark,
          1};
}

std::string CreateClientRedirect(const GURL& target_url) {
  const char* const kClientRedirectBase = "/client-redirect?";
  return kClientRedirectBase +
         net::EscapeQueryParamValue(target_url.spec(), false);
}

// Inserts an iframe in the main frame of |web_contents|.
void InsertIFrame(content::WebContents* web_contents) {
  ASSERT_TRUE(
      content::ExecuteScript(web_contents,
                             "let iframe = document.createElement('iframe');"
                             "document.body.appendChild(iframe);"));
}

void ExecuteContextMenuLinkCommandAndWait(content::WebContents* web_contents,
                                          const GURL& target_url,
                                          int command_id) {
  auto observer =
      BookmarkAppNavigationBrowserTest::GetTestNavigationObserver(target_url);
  content::ContextMenuParams params;
  params.page_url = web_contents->GetLastCommittedURL();
  params.link_url = target_url;
  TestRenderViewContextMenu menu(web_contents->GetMainFrame(), params);
  menu.Init();
  menu.ExecuteCommand(command_id, 0 /* event_flags */);
  observer->WaitForNavigationFinished();
}

void OpenPopupAndWait(content::WebContents* web_contents,
                      const GURL& target_url) {
  auto observer =
      BookmarkAppNavigationBrowserTest::GetTestNavigationObserver(target_url);
  const std::string script = base::StringPrintf(
      "(() => {"
      "  window.openedWindow = window.open('%s', '_blank', 'toolbar=no');"
      "})();",
      target_url.spec().c_str());
  ASSERT_TRUE(content::ExecuteScript(web_contents, script));
  observer->WaitForNavigationFinished();
}

// Calls window.open() with |target_url| on the main frame of |web_contents|.
// Returns once the new window has navigated to |target_url|.
void WindowOpenAndWait(content::WebContents* web_contents,
                       const GURL& target_url) {
  auto observer =
      BookmarkAppNavigationBrowserTest::GetTestNavigationObserver(target_url);
  const std::string script = base::StringPrintf(
      "(() => {"
      "  window.openedWindow = window.open('%s');"
      "})();",
      target_url.spec().c_str());
  ASSERT_TRUE(content::ExecuteScript(web_contents, script));
  observer->WaitForNavigationFinished();
}

// Calls window.open() with |target_url| on the main frame of |web_contents|.
// Returns true if the resulting child window is allowed to access members of
// its opener.
WindowAccessResult CanChildWindowAccessOpener(
    content::WebContents* web_contents,
    const GURL& target_url) {
  WindowOpenAndWait(web_contents, target_url);

  content::WebContents* new_contents =
      chrome::FindLastActive()->tab_strip_model()->GetActiveWebContents();

  const std::string script = base::StringPrintf(
      "(() => {"
      "  const [CAN_ACCESS, CANNOT_ACCESS, OTHER] = [0, 1, 2];"
      "  let result = OTHER;"
      "  try {"
      "    if (window.opener.location.href === '%s')"
      "      result = CAN_ACCESS;"
      "  } catch (e) {"
      "    if (e.name === 'SecurityError')"
      "      result = CANNOT_ACCESS;"
      "  }"
      "  window.domAutomationController.send(result);"
      "})();",
      web_contents->GetLastCommittedURL().spec().c_str());

  int access_result;
  CHECK(content::ExecuteScriptAndExtractInt(new_contents, script,
                                            &access_result));

  switch (access_result) {
    case 0:
      return WindowAccessResult::CAN_ACCESS;
    case 1:
      return WindowAccessResult::CANNOT_ACCESS;
    case 2:
      return WindowAccessResult::OTHER;
    default:
      NOTREACHED();
      return WindowAccessResult::OTHER;
  }
}

// Adds a query parameter to |base_url|.
GURL AddTestQueryParam(const GURL& base_url) {
  GURL::Replacements replacements;
  std::string query(kQueryParam);
  replacements.SetQuery(query.c_str(), url::Component(0, query.length()));
  return base_url.ReplaceComponents(replacements);
}

// Creates a <form> element with a |target_url| action and |method| method. Adds
// the form to the DOM with a button and clicks the button. Returns once
// |target_url| has been loaded.
//
// If |method| is net::URLFetcher::RequestType::GET, |target_url| should contain
// an empty query string, since that URL will be loaded when submitting the form
// e.g. "https://www.example.com/?".
void SubmitFormAndWait(content::WebContents* web_contents,
                       const GURL& target_url,
                       net::URLFetcher::RequestType method) {
  bool is_post = true;
  if (method == net::URLFetcher::RequestType::GET) {
    is_post = false;
    ASSERT_TRUE(target_url.has_query());
    ASSERT_EQ(kQueryParam, target_url.query());
  }

  BookmarkAppNavigationObserver observer(target_url);
  std::string script = base::StringPrintf(
      "(() => {"
      "const form = document.createElement('form');"
      "form.action = '%s';"
      "form.method = '%s';"
      "form.enctype = '%s';"
      "const input = document.createElement('input');"
      "input.name = '%s';"
      "form.appendChild(input);"
      "const button = document.createElement('input');"
      "button.type = 'submit';"
      "form.appendChild(button);"
      "document.body.appendChild(form);"
      "button.dispatchEvent(new MouseEvent('click', {'view': window}));"
      "})();",
      target_url.spec().c_str(),
      method == net::URLFetcher::RequestType::POST ? "post" : "get",
      kTextPlainEncType, kQueryParamName);
  ASSERT_TRUE(content::ExecuteScript(web_contents, script));
  observer.WaitForNavigationFinished();

  EXPECT_EQ(is_post, observer.last_navigation_is_post());
  if (is_post) {
    const net::HttpRequestHeaders& headers = observer.last_request_headers();
    std::string post_content_type;
    headers.GetHeader(net::HttpRequestHeaders::kContentType,
                      &post_content_type);
    EXPECT_EQ(kTextPlainEncType, post_content_type);

    const std::vector<network::DataElement>* elements =
        observer.last_resource_request_body()->elements();
    EXPECT_EQ(1u, elements->size());
    const auto& element = elements->front();

    // The text/plain enconding algorithm appends "\r\n".
    EXPECT_EQ(std::string(kQueryParam) + "\r\n",
              std::string(element.bytes(), element.length()));
  }
}

// Uses |params| to navigate to a URL. Blocks until the URL is loaded.
void NavigateToURLAndWait(NavigateParams* params) {
  auto observer =
      BookmarkAppNavigationBrowserTest::GetTestNavigationObserver(params->url);
  ui_test_utils::NavigateToURL(params);
  observer->WaitForNavigationFinished();
}

// Wrapper so that we can use base::BindOnce with NavigateToURL.
void NavigateToURLWrapper(NavigateParams* params) {
  ui_test_utils::NavigateToURL(params);
}

}  // namespace

// Tests for the behavior when the kDesktopPWAsLinkCapturing flag is on.
class BookmarkAppNavigationThrottleExperimentalBrowserTest
    : public BookmarkAppNavigationBrowserTest {
 public:
  void SetUp() override {
    scoped_feature_list_.InitWithFeatures(
        {features::kDesktopPWAWindowing, features::kDesktopPWAsLinkCapturing},
        {});
    BookmarkAppNavigationBrowserTest::SetUp();
  }

 private:
  base::test::ScopedFeatureList scoped_feature_list_;
};

// Tests that the result is the same regardless of the 'rel' attribute of links.
class BookmarkAppNavigationThrottleExperimentalLinkBrowserTest
    : public BookmarkAppNavigationThrottleExperimentalBrowserTest,
      public ::testing::WithParamInterface<std::string> {};

// Tests that navigating to the Web App's app_url doesn't open a new window
// if features::kDesktopPWAsLinkCapturing is disabled before installing the app.
IN_PROC_BROWSER_TEST_P(BookmarkAppNavigationThrottleExperimentalLinkBrowserTest,
                       FeatureDisable_BeforeInstall) {
  base::test::ScopedFeatureList feature_list;
  feature_list.InitWithFeatures({}, {features::kDesktopPWAsLinkCapturing});
  InstallTestBookmarkApp();
  NavigateToLaunchingPage();

  const GURL app_url = https_server().GetURL(GetAppUrlHost(), GetAppUrlPath());
  TestTabActionDoesNotOpenAppWindow(
      app_url,
      base::BindOnce(&ClickLinkAndWait,
                     browser()->tab_strip_model()->GetActiveWebContents(),
                     app_url, LinkTarget::SELF, GetParam()));

  ExpectNavigationResultHistogramEquals(global_histogram(), {});
}

// Tests that navigating to the Web App's app_url doesn't open a new window
// if features::kDesktopPWAWindowing is disabled after installing the app.
IN_PROC_BROWSER_TEST_P(BookmarkAppNavigationThrottleExperimentalLinkBrowserTest,
                       FeatureDisable_AfterInstall) {
  InstallTestBookmarkApp();
  base::test::ScopedFeatureList feature_list;
  feature_list.InitWithFeatures({}, {features::kDesktopPWAsLinkCapturing});
  NavigateToLaunchingPage();

  const GURL app_url = https_server().GetURL(GetAppUrlHost(), GetAppUrlPath());
  TestTabActionDoesNotOpenAppWindow(
      app_url,
      base::BindOnce(&ClickLinkAndWait,
                     browser()->tab_strip_model()->GetActiveWebContents(),
                     app_url, LinkTarget::SELF, GetParam()));

  ExpectNavigationResultHistogramEquals(global_histogram(), {});
}

// Tests that most transition types for navigations to in-scope or
// out-of-scope URLs do not result in new app windows.
class BookmarkAppNavigationThrottleExperimentalTransitionBrowserTest
    : public BookmarkAppNavigationThrottleExperimentalBrowserTest,
      public ::testing::WithParamInterface<
          std::tuple<std::string, ui::PageTransition>> {};

INSTANTIATE_TEST_CASE_P(
    /* no prefix */,
    BookmarkAppNavigationThrottleExperimentalTransitionBrowserTest,
    testing::Combine(
        testing::Values(
            BookmarkAppNavigationBrowserTest::GetInScopeUrlPath(),
            BookmarkAppNavigationBrowserTest::GetOutOfScopeUrlPath()),
        testing::Range(ui::PAGE_TRANSITION_FIRST,
                       ui::PAGE_TRANSITION_LAST_CORE)));

#if defined(OS_WIN) || defined(OS_LINUX) || defined(OS_MACOSX)
#define MAYBE_MainFrameNavigations DISABLED_MainFrameNavigations
#else
#define MAYBE_MainFrameNavigations MainFrameNavigations
#endif
IN_PROC_BROWSER_TEST_P(
    BookmarkAppNavigationThrottleExperimentalTransitionBrowserTest,
    MAYBE_MainFrameNavigations) {
  InstallTestBookmarkApp();

  GURL target_url =
      https_server().GetURL(GetAppUrlHost(), std::get<0>(GetParam()));
  ui::PageTransition transition = std::get<1>(GetParam());
  NavigateParams params(browser(), target_url, transition);

  if (!ui::PageTransitionIsMainFrame(transition)) {
    // Subframe navigations require a different setup. See
    // BookmarkAppNavigationThrottleExperimentalBrowserTest.SubframeNavigation.
    return;
  }

  if (ui::PageTransitionCoreTypeIs(ui::PAGE_TRANSITION_LINK, transition) &&
      target_url ==
          https_server().GetURL(GetAppUrlHost(), GetInScopeUrlPath())) {
    TestTabActionOpensAppWindow(target_url,
                                base::BindOnce(&NavigateToURLAndWait, &params));
  } else {
    TestTabActionDoesNotOpenAppWindow(
        target_url, base::BindOnce(&NavigateToURLAndWait, &params));
  }
}

// Tests that navigations in subframes don't open new app windows.
//
// The transition type for subframe navigations is not set until
// after NavigationThrottles run. Because of this, our
// BookmarkAppNavigationThrottle will not see the transition type as
// PAGE_TRANSITION_AUTO_SUBFRAME/PAGE_TRANSITION_MANUAL_SUBFRAME, even though,
// by the end of the navigation, the transition type is
// PAGE_TRANSITION_AUTO_SUBFRAME/PAGE_TRANSITON_MANUAL_SUBFRAME.
IN_PROC_BROWSER_TEST_F(BookmarkAppNavigationThrottleExperimentalBrowserTest,
                       AutoSubframeNavigation) {
  InstallTestBookmarkApp();
  NavigateToLaunchingPage();

  content::WebContents* initial_tab =
      browser()->tab_strip_model()->GetActiveWebContents();
  InsertIFrame(initial_tab);

  content::RenderFrameHost* iframe = GetIFrame(initial_tab);
  const GURL app_url = https_server().GetURL(GetAppUrlHost(), GetAppUrlPath());

  NavigateParams params(browser(), app_url, ui::PAGE_TRANSITION_LINK);
  params.frame_tree_node_id = iframe->GetFrameTreeNodeId();
  content::TestFrameNavigationObserver observer(iframe);
  TestIFrameActionDoesNotOpenAppWindow(
      app_url, base::BindOnce(&NavigateToURLWrapper, &params));

  ASSERT_TRUE(ui::PageTransitionCoreTypeIs(observer.transition_type(),
                                           ui::PAGE_TRANSITION_AUTO_SUBFRAME));

  // Subframe navigations are completely ignored, so there should be no change
  // in the histogram.
  ExpectNavigationResultHistogramEquals(global_histogram(), {});
}

IN_PROC_BROWSER_TEST_F(BookmarkAppNavigationThrottleExperimentalBrowserTest,
                       ManualSubframeNavigation) {
  InstallTestBookmarkApp();
  NavigateToLaunchingPage();

  content::WebContents* initial_tab =
      browser()->tab_strip_model()->GetActiveWebContents();
  InsertIFrame(initial_tab);

  {
    // Navigate the iframe once, so that the next navigation is a
    // MANUAL_SUBFRAME navigation.
    content::RenderFrameHost* iframe = GetIFrame(initial_tab);
    NavigateParams params(browser(), GetLaunchingPageURL(),
                          ui::PAGE_TRANSITION_LINK);
    params.frame_tree_node_id = iframe->GetFrameTreeNodeId();
    ASSERT_TRUE(TestIFrameActionDoesNotOpenAppWindow(
        GetLaunchingPageURL(), base::BindOnce(&NavigateToURLWrapper, &params)));
  }

  content::RenderFrameHost* iframe = GetIFrame(initial_tab);
  const GURL app_url = https_server().GetURL(GetAppUrlHost(), GetAppUrlPath());

  NavigateParams params(browser(), app_url, ui::PAGE_TRANSITION_LINK);
  params.frame_tree_node_id = iframe->GetFrameTreeNodeId();
  content::TestFrameNavigationObserver observer(iframe);
  TestIFrameActionDoesNotOpenAppWindow(
      app_url, base::BindOnce(&NavigateToURLWrapper, &params));

  ASSERT_TRUE(ui::PageTransitionCoreTypeIs(
      observer.transition_type(), ui::PAGE_TRANSITION_MANUAL_SUBFRAME));

  // Subframe navigations are completely ignored, so there should be no change
  // in the histogram.
  ExpectNavigationResultHistogramEquals(global_histogram(), {});
}

// Tests that pasting an in-scope URL into the address bar and navigating to it,
// does not open an app window.
// https://crbug.com/782004
IN_PROC_BROWSER_TEST_F(BookmarkAppNavigationThrottleExperimentalBrowserTest,
                       LinkNavigationFromAddressBar) {
  InstallTestBookmarkApp();

  const GURL app_url = https_server().GetURL(GetAppUrlHost(), GetAppUrlPath());
  // Fake a navigation with a TRANSITION_LINK core type and a
  // TRANSITION_FROM_ADDRESS_BAR qualifier. This matches the transition that
  // results from pasting a URL into the address and navigating to it.
  NavigateParams params(
      browser(), app_url,
      ui::PageTransitionFromInt(ui::PAGE_TRANSITION_LINK |
                                ui::PAGE_TRANSITION_FROM_ADDRESS_BAR));
  ASSERT_TRUE(TestTabActionDoesNotOpenAppWindow(
      app_url, base::BindOnce(&NavigateToURLWrapper, &params)));

  ExpectNavigationResultHistogramEquals(
      global_histogram(),
      {{BookmarkAppNavigationThrottleResult::kProceedTransitionFromAddressBar,
        1}});
}

// Tests that going back to an in-scope URL does not open a new app window.
IN_PROC_BROWSER_TEST_F(BookmarkAppNavigationThrottleExperimentalBrowserTest,
                       BackNavigation) {
  InstallTestBookmarkApp();
  NavigateToTestAppURL();

  // Navigate to an in-scope URL to generate a link navigation that didn't
  // get intercepted. The navigation won't get intercepted because the target
  // URL is in-scope of the app for the current URL.
  const GURL in_scope_url =
      https_server().GetURL(GetAppUrlHost(), GetInScopeUrlPath());
  ASSERT_TRUE(TestTabActionDoesNotOpenAppWindow(
      in_scope_url,
      base::BindOnce(&ClickLinkAndWait,
                     browser()->tab_strip_model()->GetActiveWebContents(),
                     in_scope_url, LinkTarget::SELF, "" /* rel */)));

  // Navigate to an out-of-scope URL.
  {
    const GURL out_of_scope_url =
        https_server().GetURL(GetAppUrlHost(), GetOutOfScopeUrlPath());
    NavigateParams params(browser(), out_of_scope_url,
                          ui::PAGE_TRANSITION_TYPED);
    ASSERT_TRUE(TestTabActionDoesNotOpenAppWindow(
        out_of_scope_url, base::BindOnce(&NavigateToURLWrapper, &params)));
  }

  base::HistogramTester scoped_histogram;
  TestTabActionDoesNotOpenAppWindow(
      in_scope_url,
      base::BindOnce(
          [](content::WebContents* web_contents, const GURL& in_scope_url) {
            auto observer = GetTestNavigationObserver(in_scope_url);
            web_contents->GetController().GoBack();
            observer->WaitForNavigationFinished();
          },
          browser()->tab_strip_model()->GetActiveWebContents(), in_scope_url));

  ExpectNavigationResultHistogramEquals(
      scoped_histogram,
      {{BookmarkAppNavigationThrottleResult::kProceedTransitionForwardBack,
        1}});
}

// Tests that clicking a link to an app that launches in a tab does not open a
// a new app window.
IN_PROC_BROWSER_TEST_P(BookmarkAppNavigationThrottleExperimentalLinkBrowserTest,
                       TabApp) {
  InstallTestBookmarkApp();

  // Set a pref indicating that the user wants to launch in a regular tab.
  extensions::SetLaunchType(browser()->profile(), test_bookmark_app()->id(),
                            extensions::LAUNCH_TYPE_REGULAR);

  NavigateToLaunchingPage();

  const GURL app_url = https_server().GetURL(GetAppUrlHost(), GetAppUrlPath());
  TestTabActionDoesNotOpenAppWindow(
      app_url,
      base::BindOnce(&ClickLinkAndWait,
                     browser()->tab_strip_model()->GetActiveWebContents(),
                     app_url, LinkTarget::SELF, GetParam()));

  // Non-windowed apps are not considered when looking for a target app, so it's
  // as if there was no app installed for the URL.
  ExpectNavigationResultHistogramEquals(global_histogram(), {});
}

// Tests that clicking a link with target="_self" to the app's app_url opens the
// Bookmark App.
IN_PROC_BROWSER_TEST_P(BookmarkAppNavigationThrottleExperimentalLinkBrowserTest,
                       AppUrlSelf) {
  InstallTestBookmarkApp();
  NavigateToLaunchingPage();

  const GURL app_url = https_server().GetURL(GetAppUrlHost(), GetAppUrlPath());
  TestTabActionOpensAppWindow(
      app_url,
      base::BindOnce(&ClickLinkAndWait,
                     browser()->tab_strip_model()->GetActiveWebContents(),
                     app_url, LinkTarget::SELF, GetParam()));

  ExpectNavigationResultHistogramEquals(
      global_histogram(),
      {{BookmarkAppNavigationThrottleResult::kCancelOpenedApp, 1},
       GetAppLaunchedEntry()});
}

// Tests that clicking a link with target="_blank" to the app's app_url opens
// the Bookmark App.
IN_PROC_BROWSER_TEST_P(BookmarkAppNavigationThrottleExperimentalLinkBrowserTest,
                       AppUrlBlank) {
  InstallTestBookmarkApp();
  NavigateToLaunchingPage();

  const GURL app_url = https_server().GetURL(GetAppUrlHost(), GetAppUrlPath());
  TestTabActionOpensAppWindow(
      app_url,
      base::BindOnce(&ClickLinkAndWait,
                     browser()->tab_strip_model()->GetActiveWebContents(),
                     app_url, LinkTarget::BLANK, GetParam()));

  ExpectNavigationResultHistogramEquals(
      global_histogram(),
      {{BookmarkAppNavigationThrottleResult::kDeferMovingContentsToNewAppWindow,
        1}});
}

// Tests that Ctrl + Clicking a link to the app's app_url opens a new background
// tab and not the app.
IN_PROC_BROWSER_TEST_P(BookmarkAppNavigationThrottleExperimentalLinkBrowserTest,
                       AppUrlCtrlClick) {
  InstallTestBookmarkApp();
  NavigateToLaunchingPage();

  const GURL app_url = https_server().GetURL(GetAppUrlPath());
  TestTabActionOpensBackgroundTab(
      app_url,
      base::BindOnce(&ClickLinkWithModifiersAndWait,
                     browser()->tab_strip_model()->GetActiveWebContents(),
                     app_url, LinkTarget::SELF, GetParam(), kCtrlOrMeta));

  ExpectNavigationResultHistogramEquals(
      global_histogram(), {{BookmarkAppNavigationThrottleResult::
                                kProceedDispositionNewBackgroundTab,
                            1}});
}

// Tests that clicking a link with target="_self" and for which the server
// redirects to the app's app_url opens the Bookmark App.
IN_PROC_BROWSER_TEST_P(BookmarkAppNavigationThrottleExperimentalLinkBrowserTest,
                       ServerRedirectToAppUrlSelf) {
  InstallTestBookmarkApp();
  NavigateToLaunchingPage();

  const GURL app_url = https_server().GetURL(GetAppUrlHost(), GetAppUrlPath());
  const GURL redirecting_url = https_server().GetURL(
      GetLaunchingPageHost(), CreateServerRedirect(app_url));
  TestTabActionOpensAppWindow(
      app_url,
      base::BindOnce(&ClickLinkAndWaitForURL,
                     browser()->tab_strip_model()->GetActiveWebContents(),
                     redirecting_url, app_url, LinkTarget::SELF, GetParam()));

  ExpectNavigationResultHistogramEquals(
      global_histogram(),
      {{BookmarkAppNavigationThrottleResult::kCancelOpenedApp, 1},
       GetAppLaunchedEntry()});
}

// Tests that clicking a link with target="_blank" and for which the server
// redirects to the app's app_url opens the Bookmark App.
IN_PROC_BROWSER_TEST_P(BookmarkAppNavigationThrottleExperimentalLinkBrowserTest,
                       ServerRedirectToAppUrlBlank) {
  InstallTestBookmarkApp();
  NavigateToLaunchingPage();

  const GURL app_url = https_server().GetURL(GetAppUrlHost(), GetAppUrlPath());
  const GURL redirecting_url = https_server().GetURL(
      GetLaunchingPageHost(), CreateServerRedirect(app_url));
  TestTabActionOpensAppWindow(
      app_url,
      base::BindOnce(&ClickLinkAndWaitForURL,
                     browser()->tab_strip_model()->GetActiveWebContents(),
                     redirecting_url, app_url, LinkTarget::BLANK, GetParam()));

  ExpectNavigationResultHistogramEquals(
      global_histogram(),
      {{BookmarkAppNavigationThrottleResult::kDeferMovingContentsToNewAppWindow,
        1}});
}

// Tests that clicking a link with target="_self" and for which the client
// redirects to the app's app_url opens the Bookmark App. The initial tab will
// be left on the redirecting URL.
IN_PROC_BROWSER_TEST_P(BookmarkAppNavigationThrottleExperimentalLinkBrowserTest,
                       ClientRedirectToAppUrlSelf) {
  InstallTestBookmarkApp();
  NavigateToLaunchingPage();

  content::WebContents* initial_tab =
      browser()->tab_strip_model()->GetActiveWebContents();
  GURL initial_url = initial_tab->GetLastCommittedURL();
  int num_tabs = browser()->tab_strip_model()->count();
  size_t num_browsers = chrome::GetBrowserCount(profile());

  const GURL app_url = https_server().GetURL(GetAppUrlHost(), GetAppUrlPath());
  const GURL redirecting_url = https_server().GetURL(
      GetLaunchingPageHost(), CreateClientRedirect(app_url));
  ClickLinkAndWaitForURL(browser()->tab_strip_model()->GetActiveWebContents(),
                         redirecting_url, app_url, LinkTarget::SELF,
                         GetParam());

  EXPECT_EQ(num_tabs, browser()->tab_strip_model()->count());
  EXPECT_EQ(++num_browsers, chrome::GetBrowserCount(profile()));
  EXPECT_NE(browser(), chrome::FindLastActive());

  EXPECT_EQ(redirecting_url, initial_tab->GetLastCommittedURL());
  EXPECT_EQ(app_url, chrome::FindLastActive()
                         ->tab_strip_model()
                         ->GetActiveWebContents()
                         ->GetLastCommittedURL());

  ExpectNavigationResultHistogramEquals(
      global_histogram(),
      {{BookmarkAppNavigationThrottleResult::kCancelOpenedApp, 1},
       GetAppLaunchedEntry()});
}

// Tests that clicking a link with target="_blank" and for which the client
// redirects to the app's app_url opens the Bookmark App. The new tab will be
// left on the redirecting URL.
IN_PROC_BROWSER_TEST_P(BookmarkAppNavigationThrottleExperimentalLinkBrowserTest,
                       ClientRedirectToAppUrlBlank) {
  InstallTestBookmarkApp();
  NavigateToLaunchingPage();

  content::WebContents* initial_tab =
      browser()->tab_strip_model()->GetActiveWebContents();
  GURL initial_url = initial_tab->GetLastCommittedURL();
  int num_tabs = browser()->tab_strip_model()->count();
  size_t num_browsers = chrome::GetBrowserCount(profile());

  const GURL app_url = https_server().GetURL(GetAppUrlHost(), GetAppUrlPath());
  const GURL redirecting_url = https_server().GetURL(
      GetLaunchingPageHost(), CreateClientRedirect(app_url));
  ClickLinkAndWaitForURL(browser()->tab_strip_model()->GetActiveWebContents(),
                         redirecting_url, app_url, LinkTarget::BLANK,
                         GetParam());

  EXPECT_EQ(++num_tabs, browser()->tab_strip_model()->count());
  EXPECT_EQ(++num_browsers, chrome::GetBrowserCount(profile()));
  EXPECT_NE(browser(), chrome::FindLastActive());

  content::WebContents* new_tab =
      browser()->tab_strip_model()->GetActiveWebContents();
  EXPECT_NE(new_tab, initial_tab);

  EXPECT_EQ(redirecting_url, new_tab->GetLastCommittedURL());
  EXPECT_EQ(app_url, chrome::FindLastActive()
                         ->tab_strip_model()
                         ->GetActiveWebContents()
                         ->GetLastCommittedURL());

  ExpectNavigationResultHistogramEquals(
      global_histogram(),
      {{BookmarkAppNavigationThrottleResult::kCancelOpenedApp, 1},
       GetAppLaunchedEntry()});
}

// Tests that clicking a link with target="_self" to a URL in the Web App's
// scope opens a new browser window.
IN_PROC_BROWSER_TEST_P(BookmarkAppNavigationThrottleExperimentalLinkBrowserTest,
                       InScopeUrlSelf) {
  InstallTestBookmarkApp();
  NavigateToLaunchingPage();

  const GURL in_scope_url =
      https_server().GetURL(GetAppUrlHost(), GetInScopeUrlPath());
  TestTabActionOpensAppWindow(
      in_scope_url,
      base::BindOnce(&ClickLinkAndWait,
                     browser()->tab_strip_model()->GetActiveWebContents(),
                     in_scope_url, LinkTarget::SELF, GetParam()));

  ExpectNavigationResultHistogramEquals(
      global_histogram(),
      {{BookmarkAppNavigationThrottleResult::kCancelOpenedApp, 1},
       GetAppLaunchedEntry()});
}

// Tests that clicking a link with target="_self" to a URL out of the Web App's
// scope but with the same origin doesn't open a new browser window.
IN_PROC_BROWSER_TEST_P(BookmarkAppNavigationThrottleExperimentalLinkBrowserTest,
                       OutOfScopeUrlSelf) {
  InstallTestBookmarkApp();
  NavigateToLaunchingPage();

  const GURL out_of_scope_url =
      https_server().GetURL(GetAppUrlHost(), GetOutOfScopeUrlPath());
  TestTabActionDoesNotOpenAppWindow(
      out_of_scope_url,
      base::BindOnce(&ClickLinkAndWait,
                     browser()->tab_strip_model()->GetActiveWebContents(),
                     out_of_scope_url, LinkTarget::SELF, GetParam()));

  ExpectNavigationResultHistogramEquals(global_histogram(), {});
}

// Tests that prerender links don't open the app.
IN_PROC_BROWSER_TEST_F(BookmarkAppNavigationThrottleExperimentalBrowserTest,
                       PrerenderLinks) {
  prerender::PrerenderManager::SetMode(
      prerender::PrerenderManager::PRERENDER_MODE_ENABLED);

  InstallTestBookmarkApp();
  NavigateToLaunchingPage();

  TestTabActionDoesNotNavigateOrOpenAppWindow(base::BindOnce(
      [](content::WebContents* web_contents, const GURL& target_url) {
        std::string script = base::StringPrintf(
            "(() => {"
            "const prerender_link = document.createElement('link');"
            "prerender_link.rel = 'prerender';"
            "prerender_link.href = '%s';"
            "prerender_link.addEventListener('webkitprerenderstop',"
            "() => window.domAutomationController.send(true));"
            "document.body.appendChild(prerender_link);"
            "})();",
            target_url.spec().c_str());
        bool result;
        ASSERT_TRUE(content::ExecuteScriptAndExtractBool(web_contents, script,
                                                         &result));
        ASSERT_TRUE(result);
      },
      browser()->tab_strip_model()->GetActiveWebContents(),
      https_server().GetURL(GetAppUrlHost(), GetInScopeUrlPath())));

  ExpectNavigationResultHistogramEquals(
      global_histogram(),
      {{BookmarkAppNavigationThrottleResult::kCancelPrerenderContents, 1}});
}

// Tests fetch calls don't open a new App window.
IN_PROC_BROWSER_TEST_F(BookmarkAppNavigationThrottleExperimentalBrowserTest,
                       Fetch) {
  InstallTestBookmarkApp();
  NavigateToLaunchingPage();

  TestTabActionDoesNotNavigateOrOpenAppWindow(base::BindOnce(
      [](content::WebContents* web_contents, const GURL& target_url) {
        std::string script = base::StringPrintf(
            "(() => {"
            "fetch('%s').then(response => {"
            "  window.domAutomationController.send(response.ok);"
            "});"
            "})();",
            target_url.spec().c_str());
        bool result;
        ASSERT_TRUE(content::ExecuteScriptAndExtractBool(web_contents, script,
                                                         &result));
        ASSERT_TRUE(result);
      },
      browser()->tab_strip_model()->GetActiveWebContents(),
      https_server().GetURL(GetAppUrlHost(), GetInScopeUrlPath())));

  // Fetch requests don't go through our NavigationHandle.
  ExpectNavigationResultHistogramEquals(global_histogram(), {});
}

// Tests that clicking "Open link in new tab" to an in-scope URL opens a new
// tab in the background.
IN_PROC_BROWSER_TEST_F(BookmarkAppNavigationThrottleExperimentalBrowserTest,
                       ContextMenuNewTab) {
  InstallTestBookmarkApp();
  NavigateToLaunchingPage();

  const GURL app_url = https_server().GetURL(GetAppUrlHost(), GetAppUrlPath());
  TestTabActionOpensBackgroundTab(
      app_url,
      base::BindOnce(&ExecuteContextMenuLinkCommandAndWait,
                     browser()->tab_strip_model()->GetActiveWebContents(),
                     app_url, IDC_CONTENT_CONTEXT_OPENLINKNEWTAB));

  ExpectNavigationResultHistogramEquals(
      global_histogram(),
      {{BookmarkAppNavigationThrottleResult::kProceedStartedFromContextMenu,
        1}});
}

// Tests that clicking "Open link in new window" to an in-scope URL opens a new
// window in the foreground.
IN_PROC_BROWSER_TEST_F(BookmarkAppNavigationThrottleExperimentalBrowserTest,
                       ContextMenuNewWindow) {
  InstallTestBookmarkApp();
  NavigateToLaunchingPage();

  const GURL app_url = https_server().GetURL(GetAppUrlHost(), GetAppUrlPath());
  TestTabActionOpensForegroundWindow(
      app_url,
      base::BindOnce(&ExecuteContextMenuLinkCommandAndWait,
                     browser()->tab_strip_model()->GetActiveWebContents(),
                     app_url, IDC_CONTENT_CONTEXT_OPENLINKNEWWINDOW));

  ExpectNavigationResultHistogramEquals(
      global_histogram(),
      {{BookmarkAppNavigationThrottleResult::kProceedStartedFromContextMenu,
        1}});
}

// Tests that clicking "Open link in new tab" in an app to an in-scope URL opens
// a new foreground tab in a regular browser window.
IN_PROC_BROWSER_TEST_F(BookmarkAppNavigationThrottleExperimentalBrowserTest,
                       InAppContextMenuNewTab) {
  InstallTestBookmarkApp();
  Browser* app_browser = OpenTestBookmarkApp();

  base::HistogramTester scoped_histogram;
  const GURL app_url = https_server().GetURL(GetAppUrlHost(), GetAppUrlPath());
  TestAppActionOpensForegroundTab(
      app_browser, app_url,
      base::BindOnce(&ExecuteContextMenuLinkCommandAndWait,
                     app_browser->tab_strip_model()->GetActiveWebContents(),
                     app_url, IDC_CONTENT_CONTEXT_OPENLINKNEWTAB));

  ExpectNavigationResultHistogramEquals(
      scoped_histogram,
      {{BookmarkAppNavigationThrottleResult::kProceedStartedFromContextMenu,
        1}});
}

// Tests that clicking "Open link in incognito window" to an in-scope URL opens
// an incognito window and not an app window.
IN_PROC_BROWSER_TEST_F(BookmarkAppNavigationThrottleExperimentalBrowserTest,
                       OpenInIncognito) {
  InstallTestBookmarkApp();
  NavigateToLaunchingPage();

  size_t num_browsers = chrome::GetBrowserCount(profile());
  int num_tabs = browser()->tab_strip_model()->count();
  content::WebContents* initial_tab =
      browser()->tab_strip_model()->GetActiveWebContents();
  GURL initial_url = initial_tab->GetLastCommittedURL();

  const GURL in_scope_url =
      https_server().GetURL(GetAppUrlHost(), GetInScopeUrlPath());
  auto observer = GetTestNavigationObserver(in_scope_url);
  content::ContextMenuParams params;
  params.page_url = initial_url;
  params.link_url = in_scope_url;
  TestRenderViewContextMenu menu(initial_tab->GetMainFrame(), params);
  menu.Init();
  menu.ExecuteCommand(IDC_CONTENT_CONTEXT_OPENLINKOFFTHERECORD,
                      0 /* event_flags */);
  observer->WaitForNavigationFinished();

  Browser* incognito_browser = chrome::FindLastActive();
  EXPECT_EQ(incognito_browser->profile(), profile()->GetOffTheRecordProfile());
  EXPECT_NE(browser(), incognito_browser);
  EXPECT_EQ(in_scope_url, incognito_browser->tab_strip_model()
                              ->GetActiveWebContents()
                              ->GetLastCommittedURL());

  EXPECT_EQ(num_browsers, chrome::GetBrowserCount(profile()));
  EXPECT_EQ(num_tabs, browser()->tab_strip_model()->count());
  EXPECT_EQ(initial_tab, browser()->tab_strip_model()->GetActiveWebContents());
  EXPECT_EQ(initial_url, initial_tab->GetLastCommittedURL());

  // Incognito navigations are completely ignored.
  ExpectNavigationResultHistogramEquals(global_histogram(), {});
}

// Tests that clicking a link to an in-scope URL when in incognito does not open
// an App window.
IN_PROC_BROWSER_TEST_P(BookmarkAppNavigationThrottleExperimentalLinkBrowserTest,
                       InScopeUrlIncognito) {
  InstallTestBookmarkApp();
  Browser* incognito_browser = CreateIncognitoBrowser();
  NavigateToLaunchingPage(incognito_browser);

  const GURL in_scope_url =
      https_server().GetURL(GetAppUrlHost(), GetInScopeUrlPath());
  TestActionDoesNotOpenAppWindow(
      incognito_browser, in_scope_url,
      base::BindOnce(
          &ClickLinkAndWait,
          incognito_browser->tab_strip_model()->GetActiveWebContents(),
          in_scope_url, LinkTarget::SELF, GetParam()));

  // Incognito navigations are completely ignored.
  ExpectNavigationResultHistogramEquals(global_histogram(), {});
}

// Tests that clicking a target=_self link from a URL out of the Web App's scope
// but with the same origin to an in-scope URL results in a new App window.
IN_PROC_BROWSER_TEST_P(BookmarkAppNavigationThrottleExperimentalLinkBrowserTest,
                       FromOutOfScopeUrlToInScopeUrlSelf) {
  InstallTestBookmarkApp();

  // Navigate to out-of-scope URL. Shouldn't open a new window.
  const GURL out_of_scope_url =
      https_server().GetURL(GetAppUrlHost(), GetOutOfScopeUrlPath());
  NavigateParams params(browser(), out_of_scope_url, ui::PAGE_TRANSITION_TYPED);
  ASSERT_TRUE(TestTabActionDoesNotOpenAppWindow(
      out_of_scope_url, base::BindOnce(&NavigateToURLWrapper, &params)));

  const GURL in_scope_url =
      https_server().GetURL(GetAppUrlHost(), GetAppUrlPath());
  TestTabActionOpensAppWindow(
      in_scope_url,
      base::BindOnce(&ClickLinkAndWait,
                     browser()->tab_strip_model()->GetActiveWebContents(),
                     in_scope_url, LinkTarget::SELF, GetParam()));

  ExpectNavigationResultHistogramEquals(
      global_histogram(),
      {{BookmarkAppNavigationThrottleResult::kCancelOpenedApp, 1},
       GetAppLaunchedEntry()});
}

// Tests that clicking a target=_blank link from a URL out of the Web App's
// scope but with the same origin to an in-scope URL results in a new App
// window.
// TODO(crbug.com/837277): Deflake and reenable.
IN_PROC_BROWSER_TEST_P(BookmarkAppNavigationThrottleExperimentalLinkBrowserTest,
                       DISABLED_FromOutOfScopeUrlToInScopeUrlBlank) {
  InstallTestBookmarkApp();

  // Navigate to out-of-scope URL. Shouldn't open a new window.
  const GURL out_of_scope_url =
      https_server().GetURL(GetAppUrlHost(), GetOutOfScopeUrlPath());
  NavigateParams params(browser(), out_of_scope_url, ui::PAGE_TRANSITION_TYPED);
  ASSERT_TRUE(TestTabActionDoesNotOpenAppWindow(
      out_of_scope_url, base::BindOnce(&NavigateToURLWrapper, &params)));

  const GURL in_scope_url =
      https_server().GetURL(GetAppUrlHost(), GetAppUrlPath());
  TestTabActionOpensAppWindow(
      in_scope_url,
      base::BindOnce(&ClickLinkAndWait,
                     browser()->tab_strip_model()->GetActiveWebContents(),
                     in_scope_url, LinkTarget::BLANK, GetParam()));

  ExpectNavigationResultHistogramEquals(
      global_histogram(),
      {{BookmarkAppNavigationThrottleResult::kDeferMovingContentsToNewAppWindow,
        1}});
}

// Tests that clicking links inside a website for an installed app doesn't open
// a new browser window.
IN_PROC_BROWSER_TEST_P(BookmarkAppNavigationThrottleExperimentalLinkBrowserTest,
                       InWebsiteNavigation) {
  InstallTestBookmarkApp();
  NavigateToTestAppURL();

  base::HistogramTester scoped_histogram;
  const GURL in_scope_url =
      https_server().GetURL(GetAppUrlHost(), GetInScopeUrlPath());
  TestTabActionDoesNotOpenAppWindow(
      in_scope_url,
      base::BindOnce(&ClickLinkAndWait,
                     browser()->tab_strip_model()->GetActiveWebContents(),
                     in_scope_url, LinkTarget::SELF, GetParam()));

  ExpectNavigationResultHistogramEquals(
      scoped_histogram,
      {{BookmarkAppNavigationThrottleResult::kProceedInBrowserSameScope, 1}});
}

class BookmarkAppNavigationThrottleExperimentalWindowOpenBrowserTest
    : public BookmarkAppNavigationThrottleExperimentalBrowserTest,
      public ::testing::WithParamInterface<std::string> {};

// Tests that same-origin or cross-origin apps created with window.open() from
// a regular browser window have an opener.
IN_PROC_BROWSER_TEST_P(
    BookmarkAppNavigationThrottleExperimentalWindowOpenBrowserTest,
    WindowOpenInBrowser) {
  InstallTestBookmarkApp();
  InstallOtherTestBookmarkApp();

  NavigateToTestAppURL();

  // Call window.open() with |target_url|.
  const GURL target_url = https_server().GetURL(GetParam(), GetAppUrlPath());
  TestTabActionOpensAppWindowWithOpener(
      target_url,
      base::BindOnce(&WindowOpenAndWait,
                     browser()->tab_strip_model()->GetActiveWebContents(),
                     target_url));
}

// Tests that same-origin or cross-origin apps created with window.open() from
// another app window have an opener.
#if defined(OS_MACOSX)
#define MAYBE_WindowOpenInApp DISABLED_WindowOpenInApp
#else
#define MAYBE_WindowOpenInApp WindowOpenInApp
#endif
IN_PROC_BROWSER_TEST_P(
    BookmarkAppNavigationThrottleExperimentalWindowOpenBrowserTest,
    MAYBE_WindowOpenInApp) {
  InstallTestBookmarkApp();
  InstallOtherTestBookmarkApp();

  // Open app window.
  Browser* app_browser = OpenTestBookmarkApp();
  content::WebContents* app_web_contents =
      app_browser->tab_strip_model()->GetActiveWebContents();

  // Call window.open() with |target_url|.
  const GURL target_url = https_server().GetURL(GetParam(), GetAppUrlPath());
  TestAppActionOpensAppWindowWithOpener(
      app_browser, target_url,
      base::BindOnce(&WindowOpenAndWait, app_web_contents, target_url));
}

INSTANTIATE_TEST_CASE_P(
    /* no prefix */,
    BookmarkAppNavigationThrottleExperimentalWindowOpenBrowserTest,
    testing::Values(BookmarkAppNavigationBrowserTest::GetAppUrlHost(),
                    BookmarkAppNavigationBrowserTest::GetOtherAppUrlHost()));

// Tests that a child window can access its opener, when the opener is a regular
// browser tab.
IN_PROC_BROWSER_TEST_F(BookmarkAppNavigationThrottleExperimentalBrowserTest,
                       AccessOpenerBrowserWindowFromChildWindow) {
  InstallTestBookmarkApp();
  InstallOtherTestBookmarkApp();

  NavigateToTestAppURL();

  content::WebContents* current_tab =
      browser()->tab_strip_model()->GetActiveWebContents();

  const GURL app_url = https_server().GetURL(GetAppUrlHost(), GetAppUrlPath());
  EXPECT_EQ(WindowAccessResult::CAN_ACCESS,
            CanChildWindowAccessOpener(current_tab, app_url));

  const GURL other_app_url =
      https_server().GetURL(GetOtherAppUrlHost(), GetAppUrlPath());
  EXPECT_EQ(WindowAccessResult::CANNOT_ACCESS,
            CanChildWindowAccessOpener(current_tab, other_app_url));
}

// Tests that a child window can access its opener, when the opener is another
// app.
IN_PROC_BROWSER_TEST_F(BookmarkAppNavigationThrottleExperimentalBrowserTest,
                       AccessOpenerAppWindowFromChildWindow) {
  InstallTestBookmarkApp();
  InstallOtherTestBookmarkApp();

  // Open app window.
  Browser* app_browser = OpenTestBookmarkApp();
  content::WebContents* app_web_contents =
      app_browser->tab_strip_model()->GetActiveWebContents();

  const GURL app_url = https_server().GetURL(GetAppUrlHost(), GetAppUrlPath());
  EXPECT_EQ(WindowAccessResult::CAN_ACCESS,
            CanChildWindowAccessOpener(app_web_contents, app_url));

  const GURL other_app_url =
      https_server().GetURL(GetOtherAppUrlHost(), GetAppUrlPath());
  EXPECT_EQ(WindowAccessResult::CANNOT_ACCESS,
            CanChildWindowAccessOpener(app_web_contents, other_app_url));
}

// Tests that in-browser navigations with all the following characteristics
// don't open a new app window or move the tab:
//  1. Are to in-scope URLs
//  2. Result in a AUTO_BOOKMARK transtion
//  3. Redirect to another in-scope URL.
//
// Clicking on sites in the New Tab Page is one of the ways to trigger this
// type of navigation.
IN_PROC_BROWSER_TEST_F(BookmarkAppNavigationThrottleExperimentalBrowserTest,
                       AutoBookmarkInScopeRedirect) {
  const Extension* app =
      InstallImmediateRedirectingApp(GetAppUrlHost(), GetInScopeUrlPath());

  const GURL app_url = AppLaunchInfo::GetFullLaunchURL(app);
  NavigateParams params(browser(), app_url, ui::PAGE_TRANSITION_AUTO_BOOKMARK);
  TestTabActionDoesNotOpenAppWindow(
      https_server().GetURL(GetAppUrlHost(), GetInScopeUrlPath()),
      base::BindOnce(&NavigateToURLWrapper, &params));

  // The first AUTO_BOOKMARK navigation is the one we triggered and the second
  // one is the redirect.
  ExpectNavigationResultHistogramEquals(
      global_histogram(),
      {{BookmarkAppNavigationThrottleResult::kProceedTransitionAutoBookmark,
        2}});
}

// Tests that in-browser navigations with all the following characteristics
// don't open a new app window or move the tab:
//  1. Are to in-scope URLs
//  2. Result in a AUTO_BOOKMARK transtion
//  3. Redirect to an out-of-scope URL.
//
// Clicking on sites in the New Tab Page is one of the ways to trigger this
// type of navigation.
IN_PROC_BROWSER_TEST_F(BookmarkAppNavigationThrottleExperimentalBrowserTest,
                       AutoBookmarkOutOfScopeRedirect) {
  const Extension* app = InstallImmediateRedirectingApp(GetLaunchingPageHost(),
                                                        GetLaunchingPagePath());

  const GURL app_url = AppLaunchInfo::GetFullLaunchURL(app);
  NavigateParams params(browser(), app_url, ui::PAGE_TRANSITION_AUTO_BOOKMARK);
  TestTabActionDoesNotOpenAppWindow(
      GetLaunchingPageURL(), base::BindOnce(&NavigateToURLWrapper, &params));

  ExpectNavigationResultHistogramEquals(
      global_histogram(),
      {{BookmarkAppNavigationThrottleResult::kProceedTransitionAutoBookmark,
        1}});
}

INSTANTIATE_TEST_CASE_P(
    /* no prefix */,
    BookmarkAppNavigationThrottleExperimentalLinkBrowserTest,
    testing::Values("", "noopener", "noreferrer", "nofollow"));

// Base class for testing the behavior is the same regardless of the
// kDesktopPWAsLinkCapturing feature flag.
class BookmarkAppNavigationThrottleBaseCommonBrowserTest
    : public BookmarkAppNavigationBrowserTest {
 protected:
  void EnableFeaturesForTest(bool should_enable_link_capturing) {
    if (should_enable_link_capturing) {
      scoped_feature_list_.InitWithFeatures(
          {features::kDesktopPWAWindowing, features::kDesktopPWAsLinkCapturing},
          {});
    } else {
      scoped_feature_list_.InitWithFeatures(
          {features::kDesktopPWAWindowing},
          {features::kDesktopPWAsLinkCapturing});
    }
  }

 private:
  base::test::ScopedFeatureList scoped_feature_list_;
};

// Class for testing the behavior is the same regardless of the
// kDesktopPWAsLinkCapturing feature flag.
class BookmarkAppNavigationThrottleCommonBrowserTest
    : public BookmarkAppNavigationThrottleBaseCommonBrowserTest,
      public ::testing::WithParamInterface<bool> {
 public:
  void SetUp() override {
    EnableFeaturesForTest(GetParam());
    BookmarkAppNavigationThrottleBaseCommonBrowserTest::SetUp();
  }
};

// Tests that an app that immediately redirects to an out-of-scope URL opens a
// new foreground tab.
IN_PROC_BROWSER_TEST_P(BookmarkAppNavigationThrottleCommonBrowserTest,
                       ImmediateOutOfScopeRedirect) {
  size_t num_browsers = chrome::GetBrowserCount(profile());
  int num_tabs_browser = browser()->tab_strip_model()->count();

  content::WebContents* initial_tab =
      browser()->tab_strip_model()->GetActiveWebContents();

  GURL initial_url = initial_tab->GetLastCommittedURL();

  const Extension* redirecting_app = InstallImmediateRedirectingApp(
      GetLaunchingPageHost(), GetLaunchingPagePath());

  auto observer = GetTestNavigationObserver(GetLaunchingPageURL());
  LaunchAppBrowser(redirecting_app);
  observer->WaitForNavigationFinished();

  EXPECT_EQ(num_browsers, chrome::GetBrowserCount(profile()));

  EXPECT_EQ(browser(), chrome::FindLastActive());
  EXPECT_EQ(++num_tabs_browser, browser()->tab_strip_model()->count());

  EXPECT_EQ(initial_url, initial_tab->GetLastCommittedURL());

  content::WebContents* new_tab =
      browser()->tab_strip_model()->GetActiveWebContents();
  EXPECT_NE(initial_tab, new_tab);
  EXPECT_EQ(GetLaunchingPageURL(), new_tab->GetLastCommittedURL());

  // When kDesktopPWAsLinkCapturing is enabled, app launches get histogrammed,
  // but when it's disabled, they don't.
  if (GetParam()) {
    ExpectNavigationResultHistogramEquals(
        global_histogram(), {GetAppLaunchedEntry(),
                             {BookmarkAppNavigationThrottleResult::
                                  kOpenInChromeProceedOutOfScopeLaunch,
                              1}});
  } else {
    ExpectNavigationResultHistogramEquals(
        global_histogram(), {{BookmarkAppNavigationThrottleResult::
                                  kOpenInChromeProceedOutOfScopeLaunch,
                              1}});
  }
}

// Tests that popups to out-of-scope URLs are opened in regular popup windows
// and not in app windows.
// TODO(crbug.com/849163) Times out flakily on MacOS.
#if defined(OS_MACOSX)
#define MAYBE_OutOfScopePopup DISABLED_OutOfScopePopup
#else
#define MAYBE_OutOfScopePopup OutOfScopePopup
#endif
IN_PROC_BROWSER_TEST_P(BookmarkAppNavigationThrottleCommonBrowserTest,
                       MAYBE_OutOfScopePopup) {
  InstallTestBookmarkApp();
  Browser* app_browser = OpenTestBookmarkApp();

  base::HistogramTester scoped_histogram;

  size_t num_browsers = chrome::GetBrowserCount(profile());
  int num_tabs_browser = browser()->tab_strip_model()->count();
  int num_tabs_app_browser = app_browser->tab_strip_model()->count();

  content::WebContents* app_web_contents =
      app_browser->tab_strip_model()->GetActiveWebContents();

  content::WebContents* initial_tab =
      browser()->tab_strip_model()->GetActiveWebContents();

  GURL initial_app_url = app_web_contents->GetLastCommittedURL();
  GURL initial_tab_url = initial_tab->GetLastCommittedURL();

  // Open a popup to an out-of-scope URL.
  const GURL out_of_scope_url =
      https_server().GetURL(GetAppUrlHost(), GetOutOfScopeUrlPath());
  OpenPopupAndWait(app_web_contents, out_of_scope_url);

  EXPECT_EQ(++num_browsers, chrome::GetBrowserCount(profile()));

  Browser* new_popup_browser = chrome::FindLastActive();
  EXPECT_NE(new_popup_browser, browser());
  EXPECT_NE(new_popup_browser, app_browser);
  EXPECT_TRUE(new_popup_browser->is_type_popup());
  EXPECT_FALSE(new_popup_browser->is_app());

  EXPECT_EQ(num_tabs_browser, browser()->tab_strip_model()->count());
  EXPECT_EQ(num_tabs_app_browser, app_browser->tab_strip_model()->count());

  EXPECT_EQ(initial_app_url, app_web_contents->GetLastCommittedURL());

  content::WebContents* new_popup_web_contents =
      new_popup_browser->tab_strip_model()->GetActiveWebContents();
  EXPECT_EQ(out_of_scope_url, new_popup_web_contents->GetLastCommittedURL());

  ExpectNavigationResultHistogramEquals(
      scoped_histogram,
      {{BookmarkAppNavigationThrottleResult::
            kReparentIntoPopupProceedOutOfScopeInitialNavigation,
        1}});
}

// Tests that popups to in-scope URLs are opened in App windows.
// TODO(crbug.com/849163) Times out flakily on MacOS.
#if defined(OS_MACOSX)
#define MAYBE_InScopePopup DISABLED_InScopePopup
#else
#define MAYBE_InScopePopup InScopePopup
#endif
IN_PROC_BROWSER_TEST_P(BookmarkAppNavigationThrottleCommonBrowserTest,
                       MAYBE_InScopePopup) {
  InstallTestBookmarkApp();
  Browser* app_browser = OpenTestBookmarkApp();

  base::HistogramTester scoped_histogram;

  // Open a popup to an out-of-scope URL.
  const GURL in_scope_url =
      https_server().GetURL(GetAppUrlHost(), GetInScopeUrlPath());
  TestAppActionOpensAppWindowWithOpener(
      app_browser, in_scope_url,
      base::Bind(&OpenPopupAndWait,
                 app_browser->tab_strip_model()->GetActiveWebContents(),
                 in_scope_url));

  ExpectNavigationResultHistogramEquals(
      scoped_histogram,
      {{BookmarkAppNavigationThrottleResult::kProceedInAppSameScope, 1}});
}

// Apps are only restored during startup on Chrome OS.
#if defined(OS_CHROMEOS)
IN_PROC_BROWSER_TEST_P(BookmarkAppNavigationThrottleCommonBrowserTest,
                       PRE_RestoreApp) {
  InstallTestBookmarkApp();
  OpenTestBookmarkApp();
  SessionStartupPref::SetStartupPref(
      profile(), SessionStartupPref(SessionStartupPref::LAST));
}

IN_PROC_BROWSER_TEST_P(BookmarkAppNavigationThrottleCommonBrowserTest,
                       RestoreApp) {
  // There should be two windows. The app window and a regular browser window
  // the test opens.
  EXPECT_EQ(2u, chrome::GetBrowserCount(profile()));
  Browser* app_browser = nullptr;
  for (auto* browser : *BrowserList::GetInstance()) {
    if (browser->is_app()) {
      EXPECT_FALSE(app_browser) << "Found multiple app browsers.";
      app_browser = browser;
    }
  }
  ASSERT_TRUE(app_browser);

  const Extension* app =
      ExtensionRegistry::Get(profile())->enabled_extensions().GetByID(
          web_app::GetExtensionIdFromApplicationName(app_browser->app_name()));
  EXPECT_EQ(GetAppName(), app->name());
}
#endif  // OS_CHROMEOS

INSTANTIATE_TEST_CASE_P(
    /* no prefix */,
    BookmarkAppNavigationThrottleCommonBrowserTest,
    testing::Bool());

// Set of tests to make sure form submissions have the correct behavior
// regardless of the kDesktopPWAsLinkCapturing feature flag.
class BookmarkAppNavigationThrottleCommonFormSubmissionBrowserTest
    : public BookmarkAppNavigationThrottleBaseCommonBrowserTest,
      public ::testing::WithParamInterface<
          std::tuple<bool,
                     StartIn,
                     std::string,
                     net::URLFetcher::RequestType,
                     std::string>> {
 public:
  void SetUp() override {
    EnableFeaturesForTest(std::get<0>(GetParam()));
    BookmarkAppNavigationThrottleBaseCommonBrowserTest::SetUp();
  }
};

IN_PROC_BROWSER_TEST_P(
    BookmarkAppNavigationThrottleCommonFormSubmissionBrowserTest,
    FormSubmission) {
  bool should_enable_link_capturing;
  StartIn start_in;
  std::string start_url_path;
  net::URLFetcher::RequestType request_type;
  std::string target_url_path;
  std::tie(should_enable_link_capturing, start_in, start_url_path, request_type,
           target_url_path) = GetParam();

  InstallTestBookmarkApp();

  // Pick where the test should start.
  Browser* current_browser;
  if (start_in == StartIn::APP)
    current_browser = OpenTestBookmarkApp();
  else
    current_browser = browser();

  // If in a regular browser window, navigate to the start URL.
  if (start_in == StartIn::BROWSER) {
    GURL start_url;
    if (start_url_path == GetLaunchingPagePath())
      start_url = GetLaunchingPageURL();
    else
      start_url = https_server().GetURL(GetAppUrlHost(), GetAppUrlPath());

    NavigateParams params(current_browser, start_url,
                          ui::PAGE_TRANSITION_TYPED);
    ASSERT_TRUE(TestTabActionDoesNotOpenAppWindow(
        start_url, base::BindOnce(&NavigateToURLWrapper, &params)));
  } else if (start_url_path == GetLaunchingPagePath()) {
    // Return early here since the app window can't start with an out-of-scope
    // URL.
    return;
  }

  // If the submit method is GET then add an query params.
  GURL target_url = https_server().GetURL(GetAppUrlHost(), target_url_path);
  if (request_type == net::URLFetcher::RequestType::GET) {
    target_url = AddTestQueryParam(target_url);
  }

  base::HistogramTester scoped_histogram;

  // All form submissions that start in the browser should be kept in the
  // browser.
  if (start_in == StartIn::BROWSER) {
    TestActionDoesNotOpenAppWindow(
        current_browser, target_url,
        base::BindOnce(
            &SubmitFormAndWait,
            current_browser->tab_strip_model()->GetActiveWebContents(),
            target_url, request_type));

    // Navigations to out-of-scope URLs are considered regular navigations and
    // therefore not recorded. Nothing gets histogrammed when
    // kDesktopPWAsLinkCapturing is disabled, because the navigation is not
    // happening in an app window.
    if (target_url_path == GetInScopeUrlPath() &&
        should_enable_link_capturing) {
      ExpectNavigationResultHistogramEquals(
          scoped_histogram, {{BookmarkAppNavigationThrottleResult::
                                  kProceedInBrowserFormSubmission,
                              1}});
    }
    return;
  }

  // When in an app, in-scope navigations should always be kept in the app
  // window.
  if (target_url_path == GetInScopeUrlPath()) {
    TestActionDoesNotOpenAppWindow(
        current_browser, target_url,
        base::BindOnce(
            &SubmitFormAndWait,
            current_browser->tab_strip_model()->GetActiveWebContents(),
            target_url, request_type));

    ExpectNavigationResultHistogramEquals(
        scoped_histogram,
        {{BookmarkAppNavigationThrottleResult::kProceedInAppSameScope, 1}});
    return;
  }

  // When in an app, out-of-scope navigations should always open a new
  // foreground tab.
  DCHECK_EQ(target_url_path, GetOutOfScopeUrlPath());
  TestAppActionOpensForegroundTab(
      current_browser, target_url,
      base::BindOnce(&SubmitFormAndWait,
                     current_browser->tab_strip_model()->GetActiveWebContents(),
                     target_url, request_type));

  ExpectNavigationResultHistogramEquals(
      scoped_histogram,
      {{BookmarkAppNavigationThrottleResult::kDeferOpenNewTabInAppOutOfScope,
        1}});
}

INSTANTIATE_TEST_CASE_P(
    /* no prefix */,
    BookmarkAppNavigationThrottleCommonFormSubmissionBrowserTest,
    testing::Combine(
        testing::Bool(),
        testing::Values(StartIn::BROWSER, StartIn::APP),
        testing::Values(
            BookmarkAppNavigationBrowserTest::GetLaunchingPagePath(),
            BookmarkAppNavigationBrowserTest::GetAppUrlPath()),
        testing::Values(net::URLFetcher::RequestType::GET,
                        net::URLFetcher::RequestType::POST),
        testing::Values(
            BookmarkAppNavigationBrowserTest::GetOutOfScopeUrlPath(),
            BookmarkAppNavigationBrowserTest::GetInScopeUrlPath())));

// Tests that the result is the same regardless of the 'rel' attribute of links
// and of the kDesktopPWAsLinkCapturing feature flag.
class BookmarkAppNavigationThrottleCommonLinkBrowserTest
    : public BookmarkAppNavigationThrottleBaseCommonBrowserTest,
      public ::testing::WithParamInterface<std::tuple<bool, std::string>> {
 public:
  void SetUp() override {
    EnableFeaturesForTest(std::get<0>(GetParam()));
    BookmarkAppNavigationThrottleBaseCommonBrowserTest::SetUp();
  }
};

// Tests that clicking links inside the app to in-scope URLs doesn't open new
// browser windows.
IN_PROC_BROWSER_TEST_P(BookmarkAppNavigationThrottleCommonLinkBrowserTest,
                       InAppInScopeNavigation) {
  InstallTestBookmarkApp();
  Browser* app_browser = OpenTestBookmarkApp();
  content::WebContents* app_web_contents =
      app_browser->tab_strip_model()->GetActiveWebContents();

  int num_tabs_browser = browser()->tab_strip_model()->count();
  int num_tabs_app_browser = app_browser->tab_strip_model()->count();
  size_t num_browsers = chrome::GetBrowserCount(profile());

  base::HistogramTester scoped_histogram;
  const GURL in_scope_url =
      https_server().GetURL(GetAppUrlHost(), GetInScopeUrlPath());
  ClickLinkAndWait(app_web_contents, in_scope_url, LinkTarget::SELF,
                   std::get<1>(GetParam()));

  EXPECT_EQ(num_tabs_browser, browser()->tab_strip_model()->count());
  EXPECT_EQ(num_tabs_app_browser, app_browser->tab_strip_model()->count());
  EXPECT_EQ(num_browsers, chrome::GetBrowserCount(profile()));
  EXPECT_EQ(app_browser, chrome::FindLastActive());

  EXPECT_EQ(in_scope_url, app_web_contents->GetLastCommittedURL());

  ExpectNavigationResultHistogramEquals(
      scoped_histogram,
      {{BookmarkAppNavigationThrottleResult::kProceedInAppSameScope, 1}});
}

// Tests that clicking links inside the app to out-of-scope URLs opens a new
// tab in an existing browser window, instead of navigating the existing
// app window.
IN_PROC_BROWSER_TEST_P(BookmarkAppNavigationThrottleCommonLinkBrowserTest,
                       InAppOutOfScopeNavigation) {
  InstallTestBookmarkApp();
  Browser* app_browser = OpenTestBookmarkApp();

  const base::HistogramTester scoped_histogram;
  const GURL out_of_scope_url =
      https_server().GetURL(GetAppUrlHost(), GetOutOfScopeUrlPath());
  TestAppActionOpensForegroundTab(
      app_browser, out_of_scope_url,
      base::BindOnce(&ClickLinkAndWait,
                     app_browser->tab_strip_model()->GetActiveWebContents(),
                     out_of_scope_url, LinkTarget::SELF,
                     std::get<1>(GetParam())));

  ExpectNavigationResultHistogramEquals(
      scoped_histogram,
      {{BookmarkAppNavigationThrottleResult::kDeferOpenNewTabInAppOutOfScope,
        1}});
}

INSTANTIATE_TEST_CASE_P(
    /* no prefix */,
    BookmarkAppNavigationThrottleCommonLinkBrowserTest,
    testing::Combine(
        testing::Bool(),
        testing::Values("", "noopener", "noreferrer", "nofollow")));

}  // namespace test
}  // namespace extensions
