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

#include <string_view>

#include "base/run_loop.h"
#include "base/test/bind.h"
#include "content/browser/renderer_host/render_frame_host_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/weak_document_ptr.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/shell/browser/shell.h"
#include "content/shell/common/render_frame_test_helper.mojom.h"
#include "content/test/content_browser_test_utils_internal.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "net/dns/mock_host_resolver.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/chrome_debug_urls.h"
#include "third_party/blink/public/common/tokens/tokens.h"
#include "url/gurl.h"

namespace content {

namespace {

// The general structure of all tests is to navigate A -> A -> B. A -> A will
// reuse the same `RenderFrameHost` (without RenderDocument) while A -> B will
// swap to a new `RenderFrameHost` (with --site-per-process).
class DocumentTokenBrowserTest : public ContentBrowserTest {
 protected:
  void SetUpOnMainThread() override {
    ContentBrowserTest::SetUpOnMainThread();

    host_resolver()->AddRule("*", "127.0.0.1");
    ASSERT_TRUE(embedded_test_server()->Start());
  }

  WebContentsImpl* web_contents() {
    return static_cast<WebContentsImpl*>(shell()->web_contents());
  }

  blink::DocumentToken GetBrowserSideToken(ToRenderFrameHost adapter) {
    return static_cast<RenderFrameHostImpl*>(adapter.render_frame_host())
        ->GetDocumentToken();
  }

  // Verifies that the browser-side `DocumentToken` and the renderer-side
  // `DocumentToken` have matching values.
  [[nodiscard]] ::testing::AssertionResult VerifyMatchingTokens(
      ToRenderFrameHost adapter) {
    blink::DocumentToken token_from_browser = GetBrowserSideToken(adapter);

    mojo::Remote<mojom::RenderFrameTestHelper> remote;
    adapter.render_frame_host()->GetRemoteInterfaces()->GetInterface(
        remote.BindNewPipeAndPassReceiver());
    blink::DocumentToken token_from_renderer;
    base::RunLoop run_loop;
    remote->GetDocumentToken(
        base::BindLambdaForTesting([&](const blink::DocumentToken& token) {
          token_from_renderer = token;
          run_loop.Quit();
        }));
    run_loop.Run();

    if (token_from_browser == token_from_renderer) {
      return ::testing::AssertionSuccess();
    }
    return ::testing::AssertionFailure()
           << "browser token was " << token_from_browser
           << " but renderer token was " << token_from_renderer;
  }

  // Whether or not `NavigateAndGetNewToken()` should wait for the response and
  // validate document token state immediately afterwards. Most tests should
  // expect and wait for a response; however, tests that are exercising
  // `CommitFailedNavigation()` will probably want to specify `kNo`.
  enum class ExpectedResponse {
    kYes,
    kNo,
  };

  // Navigate `adapter.render_frame_host()` to `target_url`. Verifies that the
  // browser and renderer state are in sync, and that the document token is not
  // updated until the navigation actually commits.
  //
  // Note: this helper makes IPCs to the `RenderFrame`; for the first navigation
  // in a WebContents, it is typically more appropriate to use `NavigateToURL()`
  // or another similar helper instead.
  blink::DocumentToken NavigateAndGetNewToken(
      ToRenderFrameHost adapter,
      const GURL& target_url,
      ExpectedResponse expect_response = ExpectedResponse::kYes) {
    SCOPED_TRACE(target_url.spec());
    // Capture the FrameTreeNode now; when a navigation commits, the current
    // RenderFrameHost may change.
    RenderFrameHostImpl* const old_render_frame_host =
        static_cast<RenderFrameHostImpl*>(adapter.render_frame_host());
    FrameTreeNode* const frame_tree_node =
        old_render_frame_host->frame_tree_node();
    const int old_process_id =
        old_render_frame_host->GetProcess()->GetDeprecatedID();
    const blink::LocalFrameToken old_frame_token =
        old_render_frame_host->GetFrameToken();
    const blink::DocumentToken old_document_token =
        GetBrowserSideToken(old_render_frame_host);
    const WeakDocumentPtr old_weak_document_ptr =
        old_render_frame_host->GetWeakDocumentPtr();
    EXPECT_EQ(old_render_frame_host, RenderFrameHostImpl::FromDocumentToken(
                                         old_process_id, old_document_token));

    // Start a new navigation in the main frame. The navigation is still
    // ongoing, so `DocumentToken` should not be updated yet.
    TestNavigationManager nav_manager(
        WebContents::FromRenderFrameHost(old_render_frame_host), target_url);
    EXPECT_TRUE(BeginNavigateToURLFromRenderer(adapter, target_url));
    EXPECT_TRUE(VerifyMatchingTokens(old_render_frame_host));
    EXPECT_EQ(old_document_token, GetBrowserSideToken(old_render_frame_host));
    EXPECT_EQ(old_render_frame_host, RenderFrameHostImpl::FromDocumentToken(
                                         old_process_id, old_document_token));

    // Just before the request is actually issued, the navigation is still
    // ongoing, so `DocumentToken` should not be updated yet.
    EXPECT_TRUE(nav_manager.WaitForRequestStart());
    EXPECT_TRUE(VerifyMatchingTokens(old_render_frame_host));
    EXPECT_EQ(old_document_token, GetBrowserSideToken(old_render_frame_host));
    EXPECT_EQ(old_render_frame_host, RenderFrameHostImpl::FromDocumentToken(
                                         old_process_id, old_document_token));

    if (ExpectedResponse::kYes == expect_response) {
      // Just before reading the response, the navigation is still ongoing, so
      // `DocumentToken` should not be updated yet.
      EXPECT_TRUE(nav_manager.WaitForResponse());
      EXPECT_TRUE(VerifyMatchingTokens(old_render_frame_host));
      EXPECT_EQ(old_document_token, GetBrowserSideToken(old_render_frame_host));
      EXPECT_EQ(old_render_frame_host, RenderFrameHostImpl::FromDocumentToken(
                                           old_process_id, old_document_token));
    }

    // Once a cross-document navigation completes, the document token should be
    // updated though.
    EXPECT_TRUE(nav_manager.WaitForNavigationFinished());
    // The RenderFrameHost may have changed; use the FrameTreeNode captured
    // above instead.
    RenderFrameHostImpl* const new_render_frame_host =
        frame_tree_node->current_frame_host();
    EXPECT_EQ(target_url, new_render_frame_host->GetLastCommittedURL());
    EXPECT_TRUE(VerifyMatchingTokens(new_render_frame_host));
    const blink::LocalFrameToken new_frame_token =
        new_render_frame_host->GetFrameToken();
    const blink::DocumentToken new_document_token =
        GetBrowserSideToken(new_render_frame_host);
    EXPECT_NE(new_document_token, old_document_token);
    if (new_frame_token == old_frame_token) {
      // If the RenderFrameHost is reused, it should no longer be possible to
      // use the old token to look up the RenderFrameHost.
      EXPECT_EQ(nullptr, RenderFrameHostImpl::FromDocumentToken(
                             old_process_id, old_document_token));
    } else if (old_weak_document_ptr.AsRenderFrameHostIfValid()) {
      // Otherwise, if the old RenderFrameHost is still around, it should still
      // map to the same RenderFrameHost.
      EXPECT_EQ(old_render_frame_host, RenderFrameHostImpl::FromDocumentToken(
                                           old_process_id, old_document_token));
    }
    EXPECT_EQ(new_render_frame_host,
              RenderFrameHostImpl::FromDocumentToken(
                  new_render_frame_host->GetProcess()->GetDeprecatedID(),
                  new_document_token));
    return new_document_token;
  }
};

IN_PROC_BROWSER_TEST_F(DocumentTokenBrowserTest, MainFrameBasic) {
  std::vector<blink::DocumentToken> seen_tokens;

  ASSERT_TRUE(NavigateToURL(
      web_contents(), embedded_test_server()->GetURL("a.com", "/title1.html")));
  EXPECT_TRUE(VerifyMatchingTokens(web_contents()));
  seen_tokens.push_back(GetBrowserSideToken(web_contents()));

  seen_tokens.push_back(NavigateAndGetNewToken(
      web_contents(), embedded_test_server()->GetURL("a.com", "/title1.html")));

  seen_tokens.push_back(NavigateAndGetNewToken(
      web_contents(), embedded_test_server()->GetURL("b.com", "/title1.html")));

  std::set unique_tokens(seen_tokens.begin(), seen_tokens.end());
  EXPECT_EQ(unique_tokens.size(), seen_tokens.size());
}

IN_PROC_BROWSER_TEST_F(DocumentTokenBrowserTest, SubFrameBasic) {
  std::vector<blink::DocumentToken> seen_tokens;

  ASSERT_TRUE(NavigateToURL(
      web_contents(), embedded_test_server()->GetURL(
                          "a.com", "/cross_site_iframe_factory.html?a(a)")));
  EXPECT_TRUE(VerifyMatchingTokens(web_contents()));
  EXPECT_TRUE(VerifyMatchingTokens(ChildFrameAt(web_contents(), 0)));
  seen_tokens.push_back(GetBrowserSideToken(web_contents()));
  seen_tokens.push_back(GetBrowserSideToken(ChildFrameAt(web_contents(), 0)));

  seen_tokens.push_back(NavigateAndGetNewToken(
      ChildFrameAt(web_contents(), 0),
      embedded_test_server()->GetURL("a.com", "/title1.html")));
  // Main document did not navigate so the token should be the same.
  EXPECT_EQ(seen_tokens[0], GetBrowserSideToken(web_contents()));

  seen_tokens.push_back(NavigateAndGetNewToken(
      ChildFrameAt(web_contents(), 0),
      embedded_test_server()->GetURL("b.com", "/title1.html")));
  // Main document did not navigate so the token should be the same.
  EXPECT_EQ(seen_tokens[0], GetBrowserSideToken(web_contents()));

  std::set unique_tokens(seen_tokens.begin(), seen_tokens.end());
  EXPECT_EQ(unique_tokens.size(), seen_tokens.size());
}

IN_PROC_BROWSER_TEST_F(DocumentTokenBrowserTest, NewWindowBasic) {
  std::vector<blink::DocumentToken> seen_tokens;

  ASSERT_TRUE(NavigateToURL(
      web_contents(), embedded_test_server()->GetURL("a.com", "/title1.html")));
  EXPECT_EQ(1u, Shell::windows().size());
  seen_tokens.push_back(GetBrowserSideToken(web_contents()));

  WebContents* new_contents = nullptr;
  {
    // This block is largely derived from `NavigateAndGetNewToken()`. This test
    // cannot easily reuse that helper because:
    //
    // - it is important to specify an actual target URL other than about:blank
    //   for `window.open()`. Specifying no target URL and then later navigating
    //   the window has subtly different behavior (e.g. the
    //   `NewWindowSyncCommit` test below).
    // - the helper expects the `WebContents` to already exist in order to
    // install
    //   `TestNavigationManager`. However, in this test, a new `WebContents` is
    //   created in the process of running the test.
    ExecuteScriptAsync(web_contents(), JsReplace("window.open($1)",
                                                 embedded_test_server()->GetURL(
                                                     "a.com", "/title1.html")));
    ShellAddedObserver wait_for_new_shell;
    new_contents = wait_for_new_shell.GetShell()->web_contents();
    DCHECK_EQ(2u, Shell::windows().size());
    DCHECK_EQ(new_contents, Shell::windows()[1]->web_contents());
    DCHECK_NE(new_contents, web_contents());
    seen_tokens.push_back(GetBrowserSideToken(new_contents));
    TestNavigationManager nav_manager(
        new_contents, embedded_test_server()->GetURL("a.com", "/title1.html"));

    // Capture the FrameTreeNode now; when a navigation commits, the current
    // RenderFrameHost may change.
    RenderFrameHostImpl* const old_render_frame_host =
        static_cast<RenderFrameHostImpl*>(new_contents->GetPrimaryMainFrame());
    FrameTreeNode* const frame_tree_node =
        old_render_frame_host->frame_tree_node();
    const int old_process_id =
        old_render_frame_host->GetProcess()->GetDeprecatedID();
    const blink::LocalFrameToken old_frame_token =
        old_render_frame_host->GetFrameToken();
    const blink::DocumentToken old_document_token =
        GetBrowserSideToken(new_contents);
    const WeakDocumentPtr old_weak_document_ptr =
        old_render_frame_host->GetWeakDocumentPtr();

    EXPECT_TRUE(VerifyMatchingTokens(new_contents));
    EXPECT_EQ(old_document_token, GetBrowserSideToken(new_contents));
    EXPECT_EQ(old_render_frame_host, RenderFrameHostImpl::FromDocumentToken(
                                         old_process_id, old_document_token));
    // Even after creating a new window, the original `WebContents` should still
    // have the same `DocumentToken`.
    EXPECT_EQ(seen_tokens[0], GetBrowserSideToken(web_contents()));

    // Just before the request is actually issued, the navigation is still
    // ongoing, so `DocumentToken` should not be updated yet.
    EXPECT_TRUE(nav_manager.WaitForRequestStart());
    EXPECT_TRUE(VerifyMatchingTokens(new_contents));
    EXPECT_EQ(old_document_token, GetBrowserSideToken(new_contents));
    EXPECT_EQ(old_render_frame_host, RenderFrameHostImpl::FromDocumentToken(
                                         old_process_id, old_document_token));
    // The original `WebContents` should still have the same `DocumentToken`.
    EXPECT_EQ(seen_tokens[0], GetBrowserSideToken(web_contents()));

    // Just before reading the response, the navigation is still ongoing, so
    // `DocumentToken` should not be updated yet.
    EXPECT_TRUE(nav_manager.WaitForResponse());
    EXPECT_TRUE(VerifyMatchingTokens(new_contents));
    EXPECT_EQ(old_document_token, GetBrowserSideToken(new_contents));
    EXPECT_EQ(old_render_frame_host, RenderFrameHostImpl::FromDocumentToken(
                                         old_process_id, old_document_token));
    // The original `WebContents` should still have the same `DocumentToken`.
    EXPECT_EQ(seen_tokens[0], GetBrowserSideToken(web_contents()));

    // Once a cross-document navigation completes, the document token should be
    // updated though.
    ASSERT_TRUE(nav_manager.WaitForNavigationFinished());
    // The RenderFrameHost may have changed; use the FrameTreeNode captured
    // above instead.
    RenderFrameHostImpl* const new_render_frame_host =
        frame_tree_node->current_frame_host();
    EXPECT_EQ(embedded_test_server()->GetURL("a.com", "/title1.html"),
              new_render_frame_host->GetLastCommittedURL());
    EXPECT_TRUE(VerifyMatchingTokens(new_render_frame_host));
    const blink::LocalFrameToken new_frame_token =
        new_render_frame_host->GetFrameToken();
    const blink::DocumentToken new_document_token =
        GetBrowserSideToken(new_render_frame_host);
    EXPECT_NE(new_document_token, old_document_token);
    if (new_frame_token == old_frame_token) {
      // If the RenderFrameHost is reused, it should no longer be possible to
      // use the old token to look up the RenderFrameHost.
      EXPECT_EQ(nullptr, RenderFrameHostImpl::FromDocumentToken(
                             old_process_id, old_document_token));
    } else if (old_weak_document_ptr.AsRenderFrameHostIfValid()) {
      // Otherwise, if the old RenderFrameHost is still around, it should still
      // map to the same RenderFrameHost.
      EXPECT_EQ(old_render_frame_host, RenderFrameHostImpl::FromDocumentToken(
                                           old_process_id, old_document_token));
    }
    EXPECT_EQ(new_render_frame_host,
              RenderFrameHostImpl::FromDocumentToken(
                  new_render_frame_host->GetProcess()->GetDeprecatedID(),
                  new_document_token));
    seen_tokens.push_back(new_document_token);
    // The original `WebContents` should still have the same `DocumentToken`.
    EXPECT_EQ(seen_tokens[0], GetBrowserSideToken(web_contents()));
  }

  seen_tokens.push_back(NavigateAndGetNewToken(
      new_contents, embedded_test_server()->GetURL("a.com", "/title1.html")));
  // The original `WebContents` should still have the same `DocumentToken`.
  EXPECT_EQ(seen_tokens[0], GetBrowserSideToken(web_contents()));

  seen_tokens.push_back(NavigateAndGetNewToken(
      new_contents, embedded_test_server()->GetURL("b.com", "/title1.html")));
  // The original `WebContents` should still have the same `DocumentToken`.
  EXPECT_EQ(seen_tokens[0], GetBrowserSideToken(web_contents()));

  std::set unique_tokens(seen_tokens.begin(), seen_tokens.end());
  EXPECT_EQ(unique_tokens.size(), seen_tokens.size());
}

IN_PROC_BROWSER_TEST_F(DocumentTokenBrowserTest, SubFrameSyncCommit) {
  std::vector<blink::DocumentToken> seen_tokens;

  // This is a basic test that the synchronous commit of about:blank reuses the
  // same DocumentToken. See https://crbug.com/778318 for more details.
  ASSERT_TRUE(NavigateToURL(
      web_contents(),
      embedded_test_server()->GetURL("a.com", "/page_with_blank_iframe.html")));
  EXPECT_TRUE(VerifyMatchingTokens(web_contents()));
  EXPECT_TRUE(VerifyMatchingTokens(ChildFrameAt(web_contents(), 0)));
  seen_tokens.push_back(GetBrowserSideToken(web_contents()));
  seen_tokens.push_back(GetBrowserSideToken(ChildFrameAt(web_contents(), 0)));

  seen_tokens.push_back(NavigateAndGetNewToken(
      ChildFrameAt(web_contents(), 0),
      embedded_test_server()->GetURL("a.com", "/title1.html")));
  // Main document did not navigate so the token should be the same.
  EXPECT_EQ(seen_tokens[0], GetBrowserSideToken(web_contents()));

  seen_tokens.push_back(NavigateAndGetNewToken(
      ChildFrameAt(web_contents(), 0),
      embedded_test_server()->GetURL("b.com", "/title1.html")));
  // Main document did not navigate so the token should be the same.
  EXPECT_EQ(seen_tokens[0], GetBrowserSideToken(web_contents()));

  std::set unique_tokens(seen_tokens.begin(), seen_tokens.end());
  EXPECT_EQ(unique_tokens.size(), seen_tokens.size());
}

IN_PROC_BROWSER_TEST_F(DocumentTokenBrowserTest, NewWindowSyncCommit) {
  std::vector<blink::DocumentToken> seen_tokens;

  ASSERT_TRUE(NavigateToURL(web_contents(), GURL("about:blank")));
  EXPECT_EQ(1u, Shell::windows().size());
  EXPECT_TRUE(VerifyMatchingTokens(web_contents()));
  seen_tokens.push_back(GetBrowserSideToken(web_contents()));

  // This is a basic test that the synchronous commit of about:blank reuses the
  // same DocumentToken. See https://crbug.com/778318 for more details.
  ASSERT_TRUE(ExecJs(web_contents(), "window.open()"));
  ASSERT_EQ(2u, Shell::windows().size());
  WebContents* new_contents = Shell::windows()[1]->web_contents();
  DCHECK_NE(new_contents, web_contents());
  EXPECT_TRUE(VerifyMatchingTokens(new_contents));
  // The original `WebContents` should still have the same `DocumentToken`.
  EXPECT_EQ(seen_tokens[0], GetBrowserSideToken(web_contents()));

  seen_tokens.push_back(NavigateAndGetNewToken(
      new_contents, embedded_test_server()->GetURL("a.com", "/title1.html")));
  // The original `WebContents` should still have the same `DocumentToken`.
  EXPECT_EQ(seen_tokens[0], GetBrowserSideToken(web_contents()));

  seen_tokens.push_back(NavigateAndGetNewToken(
      new_contents, embedded_test_server()->GetURL("a.com", "/title1.html")));
  // The original `WebContents` should still have the same `DocumentToken`.
  EXPECT_EQ(seen_tokens[0], GetBrowserSideToken(web_contents()));

  seen_tokens.push_back(NavigateAndGetNewToken(
      new_contents, embedded_test_server()->GetURL("b.com", "/title1.html")));
  // The original `WebContents` should still have the same `DocumentToken`.
  EXPECT_EQ(seen_tokens[0], GetBrowserSideToken(web_contents()));

  std::set unique_tokens(seen_tokens.begin(), seen_tokens.end());
  EXPECT_EQ(unique_tokens.size(), seen_tokens.size());
}

IN_PROC_BROWSER_TEST_F(DocumentTokenBrowserTest, JavascriptURL) {
  ASSERT_TRUE(NavigateToURL(
      web_contents(), embedded_test_server()->GetURL("a.com", "/title1.html")));
  EXPECT_TRUE(VerifyMatchingTokens(web_contents()));
  const blink::DocumentToken token = GetBrowserSideToken(web_contents());

  // A javascript: navigation that replaces the document should not change the
  // DocumentToken. This does not use the normal Navigate*() helpers since it
  // does not commit a normal cross-document navigation.
  ASSERT_TRUE(ExecJs(web_contents(),
                     JsReplace("location = $1", "javascript:'Hello world!'")));
  EXPECT_EQ("Hello world!", EvalJs(web_contents(), "document.body.innerText"));
  EXPECT_TRUE(VerifyMatchingTokens(web_contents()));
  EXPECT_EQ(token, GetBrowserSideToken(web_contents()));
}

IN_PROC_BROWSER_TEST_F(DocumentTokenBrowserTest, FailedNavigation) {
  std::vector<blink::DocumentToken> seen_tokens;

  ASSERT_TRUE(NavigateToURL(
      web_contents(), embedded_test_server()->GetURL("a.com", "/title1.html")));
  EXPECT_TRUE(VerifyMatchingTokens(web_contents()));
  seen_tokens.push_back(GetBrowserSideToken(web_contents()));

  seen_tokens.push_back(NavigateAndGetNewToken(
      web_contents(), embedded_test_server()->GetURL("a.com", "/close-socket"),
      ExpectedResponse::kNo));

  seen_tokens.push_back(NavigateAndGetNewToken(
      web_contents(), embedded_test_server()->GetURL("a.com", "/close-socket"),
      ExpectedResponse::kNo));

  seen_tokens.push_back(NavigateAndGetNewToken(
      web_contents(), embedded_test_server()->GetURL("b.com", "/close-socket"),
      ExpectedResponse::kNo));

  // Test that a regular successful navigation still updates the document token.
  seen_tokens.push_back(NavigateAndGetNewToken(
      web_contents(), embedded_test_server()->GetURL("a.com", "/title1.html")));

  std::set unique_tokens(seen_tokens.begin(), seen_tokens.end());
  EXPECT_EQ(unique_tokens.size(), seen_tokens.size());
}

IN_PROC_BROWSER_TEST_F(DocumentTokenBrowserTest, CrashThenReload) {
  ASSERT_TRUE(NavigateToURL(
      web_contents(), embedded_test_server()->GetURL("a.com", "/title1.html")));
  EXPECT_TRUE(VerifyMatchingTokens(web_contents()));
  const int old_process_id =
      web_contents()->GetPrimaryMainFrame()->GetProcess()->GetDeprecatedID();
  const blink::DocumentToken old_document_token =
      GetBrowserSideToken(web_contents());

  // Cause the renderer to crash.
  RenderProcessHostWatcher crash_observer(
      web_contents(), RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
  EXPECT_FALSE(NavigateToURL(shell(), GURL(blink::kChromeUICrashURL)));
  // Wait for browser to notice the renderer crash.
  crash_observer.Wait();

  // After a crash, the DocumentToken should still be the same even though the
  // renderer process is gone..
  EXPECT_EQ(old_document_token, GetBrowserSideToken(web_contents()));

  // But when a live RenderFrame is needed again, RenderDocument should force a
  // new RenderFrameHost, and thus, a new DocumentToken. The remainder of this
  // test does not use `NavigateAndGetNewToken()`, which tries to use a
  // renderer-initiated navigation (which is not possible when the renderer is
  // not live).
  TestNavigationManager nav_manager(
      web_contents(), embedded_test_server()->GetURL("a.com", "/title1.html"));
  shell()->LoadURL(embedded_test_server()->GetURL("a.com", "/title1.html"));
  EXPECT_TRUE(VerifyMatchingTokens(web_contents()));
  const int new_process_id =
      web_contents()->GetPrimaryMainFrame()->GetProcess()->GetDeprecatedID();
  const blink::DocumentToken token_after_navigation_started =
      GetBrowserSideToken(web_contents());
  EXPECT_NE(token_after_navigation_started, old_document_token);
  const WeakDocumentPtr document_weak_ptr =
      web_contents()->GetPrimaryMainFrame()->GetWeakDocumentPtr();
  EXPECT_EQ(web_contents()->GetPrimaryMainFrame(),
            RenderFrameHostImpl::FromDocumentToken(
                new_process_id, token_after_navigation_started));
  // The old RenderFrameHost should be gone at this point, so a document token
  // lookup should fail.
  EXPECT_EQ(nullptr, RenderFrameHostImpl::FromDocumentToken(
                         old_process_id, old_document_token));

  // After the navigation finishes, the RenderFrameHost will still use the same
  // DocumentToken, since no new DocumentAssociatedData was created. The latter
  // is indirectly tested by checking if the WeakDocumentPtr is still valid
  // after the navigation commits.
  ASSERT_TRUE(nav_manager.WaitForNavigationFinished());
  EXPECT_TRUE(VerifyMatchingTokens(web_contents()));
  const blink::DocumentToken token_after_navigation_finished =
      GetBrowserSideToken(web_contents());
  EXPECT_NE(token_after_navigation_finished, old_document_token);
  EXPECT_EQ(token_after_navigation_finished, token_after_navigation_started);
  EXPECT_NE(document_weak_ptr.AsRenderFrameHostIfValid(), nullptr);
  EXPECT_EQ(web_contents()->GetPrimaryMainFrame(),
            RenderFrameHostImpl::FromDocumentToken(
                new_process_id, token_after_navigation_started));
}

IN_PROC_BROWSER_TEST_F(DocumentTokenBrowserTest,
                       CrashThenImmediateReinitialize) {
  ASSERT_TRUE(NavigateToURL(
      web_contents(), embedded_test_server()->GetURL("a.com", "/title1.html")));
  EXPECT_TRUE(VerifyMatchingTokens(web_contents()));
  RenderFrameHostImpl* main_frame = web_contents()->GetPrimaryMainFrame();
  const blink::LocalFrameToken frame_token = main_frame->GetFrameToken();
  const blink::DocumentToken old_document_token =
      GetBrowserSideToken(main_frame);
  const WeakDocumentPtr document_weak_ptr = main_frame->GetWeakDocumentPtr();

  // Cause the renderer to crash.
  RenderProcessHostWatcher crash_observer(
      web_contents(), RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
  EXPECT_FALSE(NavigateToURL(shell(), GURL(blink::kChromeUICrashURL)));
  // Wait for browser to notice the renderer crash.
  crash_observer.Wait();

  // If the main render frame is re-initialized, it also gets a new
  // DocumentAssociatedData. Validate that the new DocumentAssociatedData is
  // created before the renderer is re-created; a typical failure in this path
  // will manifest as a mismatch between the browser and renderer-side document
  // tokens.
  main_frame->frame_tree_node()
      ->render_manager()
      ->InitializeMainRenderFrameForImmediateUse();
  // The RenderFrameHost should be reused.
  ASSERT_EQ(frame_token,
            web_contents()->GetPrimaryMainFrame()->GetFrameToken());
  EXPECT_TRUE(VerifyMatchingTokens(web_contents()));
  // The re-created RenderFrame should have a distinct document token.
  const blink::DocumentToken new_document_token =
      GetBrowserSideToken(web_contents());
  EXPECT_NE(new_document_token, old_document_token);
  // The previous DocumentWeakPtr should be invalidated since the
  // DocumentAssociatedData was re-created.
  EXPECT_FALSE(document_weak_ptr.AsRenderFrameHostIfValid());
  // Even though the RenderFrameHost did not change, only a lookup using the new
  // DocumentToken should succeed.
  EXPECT_EQ(web_contents()->GetPrimaryMainFrame(),
            RenderFrameHostImpl::FromDocumentToken(web_contents()
                                                       ->GetPrimaryMainFrame()
                                                       ->GetProcess()
                                                       ->GetDeprecatedID(),
                                                   new_document_token));
  EXPECT_EQ(nullptr,
            RenderFrameHostImpl::FromDocumentToken(web_contents()
                                                       ->GetPrimaryMainFrame()
                                                       ->GetProcess()
                                                       ->GetDeprecatedID(),
                                                   old_document_token));
}

// TODO(crbug.com/40238502): Add tests for bfcache navigations and
// prerender activations.

IN_PROC_BROWSER_TEST_F(DocumentTokenBrowserTest, MismatchedProcessID) {
  RenderFrameHostImpl* main_frame = web_contents()->GetPrimaryMainFrame();
  bool called = false;
  mojo::ReportBadMessageCallback callback =
      base::BindLambdaForTesting([&called](std::string_view reason) {
        called = true;
        EXPECT_EQ("process ID does not match requested DocumentToken", reason);
      });
  EXPECT_EQ(nullptr, RenderFrameHostImpl::FromDocumentToken(
                         main_frame->GetProcess()->GetDeprecatedID() + 1,
                         main_frame->GetDocumentToken(), &callback));
  EXPECT_TRUE(called);
}

}  // namespace

}  // namespace content
