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

#include <stddef.h>

#include "build/build_config.h"
#include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/bookmarks/bookmark_model_factory.h"
#include "chrome/browser/ui/browser_command_controller.h"
#include "chrome/browser/ui/browser_commands.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/browser/ui/zoom/chrome_zoom_level_prefs.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/base/browser_with_test_window_test.h"
#include "chrome/test/base/testing_profile.h"
#include "components/bookmarks/browser/bookmark_model.h"
#include "components/bookmarks/test/bookmark_test_helpers.h"
#include "components/zoom/page_zoom.h"
#include "components/zoom/zoom_controller.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/page_zoom.h"
#include "content/public/test/navigation_simulator.h"
#include "content/public/test/test_renderer_host.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/page/page_zoom.h"
#include "third_party/blink/public/common/renderer_preferences/renderer_preferences.h"

namespace {

using bookmarks::BookmarkModel;
using content::OpenURLParams;
using content::Referrer;
using content::WebContents;
using zoom::ZoomController;

class BrowserCommandsTest : public BrowserWithTestWindowTest {
 public:
  BrowserCommandsTest() = default;
  ~BrowserCommandsTest() override = default;

  // BrowserWithTestWindowTest overrides.
  TestingProfile::TestingFactories GetTestingFactories() override {
    return {{BookmarkModelFactory::GetInstance(),
             BookmarkModelFactory::GetDefaultFactory()}};
  }
};

// Tests IDC_SELECT_TAB_0, IDC_SELECT_NEXT_TAB, IDC_SELECT_PREVIOUS_TAB and
// IDC_SELECT_LAST_TAB.
TEST_F(BrowserCommandsTest, TabNavigationAccelerators) {
  GURL about_blank(url::kAboutBlankURL);

  // Create three tabs.
  AddTab(browser(), about_blank);
  AddTab(browser(), about_blank);
  AddTab(browser(), about_blank);

  // Select the second tab.
  browser()->tab_strip_model()->ActivateTabAt(1);

  CommandUpdater* updater = browser()->command_controller();

  // Navigate to the first tab using an accelerator.
  updater->ExecuteCommand(IDC_SELECT_TAB_0);
  ASSERT_EQ(0, browser()->tab_strip_model()->active_index());

  // Navigate to the second tab using the next accelerators.
  updater->ExecuteCommand(IDC_SELECT_NEXT_TAB);
  ASSERT_EQ(1, browser()->tab_strip_model()->active_index());

  // Navigate back to the first tab using the previous accelerators.
  updater->ExecuteCommand(IDC_SELECT_PREVIOUS_TAB);
  ASSERT_EQ(0, browser()->tab_strip_model()->active_index());

  // Navigate to the last tab using the select last accelerator.
  updater->ExecuteCommand(IDC_SELECT_LAST_TAB);
  ASSERT_EQ(2, browser()->tab_strip_model()->active_index());
}

// Tests IDC_DUPLICATE_TAB.
TEST_F(BrowserCommandsTest, DuplicateTab) {
  GURL url1("http://foo/1");
  GURL url2("http://foo/2");
  GURL url3("http://foo/3");
  GURL url4("http://foo/4");

  // Navigate to three urls, plus a pending URL that hasn't committed.
  AddTab(browser(), url1);
  NavigateAndCommitActiveTab(url2);
  NavigateAndCommitActiveTab(url3);
  content::NavigationController& orig_controller =
      browser()->tab_strip_model()->GetWebContentsAt(0)->GetController();
  orig_controller.LoadURL(
      url4, content::Referrer(), ui::PAGE_TRANSITION_LINK, std::string());
  EXPECT_EQ(3, orig_controller.GetEntryCount());
  EXPECT_TRUE(orig_controller.GetPendingEntry());

  size_t initial_window_count = chrome::GetTotalBrowserCount();

  // Duplicate the tab.
  chrome::ExecuteCommand(browser(), IDC_DUPLICATE_TAB);

  // The duplicated tab should not end up in a new window.
  size_t window_count = chrome::GetTotalBrowserCount();
  ASSERT_EQ(initial_window_count, window_count);

  // And we should have a newly duplicated tab.
  ASSERT_EQ(2, browser()->tab_strip_model()->count());

  // Verify the stack of urls.
  content::NavigationController& controller =
      browser()->tab_strip_model()->GetWebContentsAt(1)->GetController();
  EXPECT_EQ(3, controller.GetEntryCount());
  EXPECT_EQ(2, controller.GetCurrentEntryIndex());
  EXPECT_EQ(url1, controller.GetEntryAtIndex(0)->GetURL());
  EXPECT_EQ(url2, controller.GetEntryAtIndex(1)->GetURL());
  EXPECT_EQ(url3, controller.GetEntryAtIndex(2)->GetURL());
  EXPECT_FALSE(controller.GetPendingEntry());
}

// Tests IDC_VIEW_SOURCE (See http://crbug.com/138140).
TEST_F(BrowserCommandsTest, ViewSource) {
  GURL url1("http://foo/1");
  GURL url1_subframe("http://foo/subframe");
  GURL url2("http://foo/2");

  // Navigate to a URL and simulate a subframe committing.
  AddTab(browser(), url1);
  content::RenderFrameHostTester* rfh_tester =
      content::RenderFrameHostTester::For(browser()
                                              ->tab_strip_model()
                                              ->GetWebContentsAt(0)
                                              ->GetPrimaryMainFrame());
  content::RenderFrameHost* subframe = rfh_tester->AppendChild("subframe");
  content::NavigationSimulator::NavigateAndCommitFromDocument(
      GURL(url1_subframe), subframe);

  // Now start a pending navigation that hasn't committed.
  content::NavigationController& orig_controller =
      browser()->tab_strip_model()->GetWebContentsAt(0)->GetController();
  orig_controller.LoadURL(
      url2, content::Referrer(), ui::PAGE_TRANSITION_LINK, std::string());
  EXPECT_EQ(1, orig_controller.GetEntryCount());
  EXPECT_TRUE(orig_controller.GetPendingEntry());

  size_t initial_window_count = chrome::GetTotalBrowserCount();

  // View Source.
  chrome::ExecuteCommand(browser(), IDC_VIEW_SOURCE);

  // The view source tab should not end up in a new window.
  size_t window_count = chrome::GetTotalBrowserCount();
  ASSERT_EQ(initial_window_count, window_count);

  // And we should have a newly duplicated tab.
  ASSERT_EQ(2, browser()->tab_strip_model()->count());

  // Verify we are viewing the source of the last committed entry.
  GURL view_source_url("view-source:http://foo/1");
  content::NavigationController& controller =
      browser()->tab_strip_model()->GetWebContentsAt(1)->GetController();
  EXPECT_EQ(1, controller.GetEntryCount());
  EXPECT_EQ(0, controller.GetCurrentEntryIndex());
  EXPECT_EQ(url1, controller.GetEntryAtIndex(0)->GetURL());
  EXPECT_EQ(view_source_url, controller.GetEntryAtIndex(0)->GetVirtualURL());
  EXPECT_FALSE(controller.GetPendingEntry());
}

TEST_F(BrowserCommandsTest, BookmarkCurrentTab) {
  BookmarkModel* model = BookmarkModelFactory::GetForBrowserContext(profile());
  bookmarks::test::WaitForBookmarkModelToLoad(model);

  // Navigate to a url.
  GURL url1("http://foo/1");
  AddTab(browser(), url1);
  browser()->OpenURL(OpenURLParams(url1, Referrer(),
                                   WindowOpenDisposition::CURRENT_TAB,
                                   ui::PAGE_TRANSITION_TYPED, false));

  chrome::BookmarkCurrentTab(browser());

  // It should now be bookmarked in the bookmark model.
  EXPECT_EQ(profile(), browser()->profile());
  EXPECT_TRUE(model->IsBookmarked(url1));
}

// Tests back/forward in new tab (Control + Back/Forward button in the UI).
TEST_F(BrowserCommandsTest, BackForwardInNewTab) {
  GURL url1("http://foo/1");
  GURL url2("http://foo/2");

  // Make a tab with the two pages navigated in it.
  AddTab(browser(), url1);
  NavigateAndCommitActiveTab(url2);

  // Go back in a new background tab.
  chrome::GoBack(browser(), WindowOpenDisposition::NEW_BACKGROUND_TAB);
  EXPECT_EQ(0, browser()->tab_strip_model()->active_index());
  ASSERT_EQ(2, browser()->tab_strip_model()->count());

  WebContents* zeroth = browser()->tab_strip_model()->GetWebContentsAt(0);
  WebContents* first = browser()->tab_strip_model()->GetWebContentsAt(1);

  // The original tab should be unchanged.
  EXPECT_EQ(url2, zeroth->GetLastCommittedURL());
  EXPECT_TRUE(zeroth->GetController().CanGoBack());
  EXPECT_FALSE(zeroth->GetController().CanGoForward());

  // The new tab should be like the first one but navigated back. Since we
  // didn't wait for the load to complete, we can't use GetLastCommittedURL.
  EXPECT_EQ(url1, first->GetVisibleURL());
  EXPECT_FALSE(first->GetController().CanGoBack());
  EXPECT_TRUE(first->GetController().CanGoForward());

  // Select the second tab and make it go forward in a new background tab.
  browser()->tab_strip_model()->ActivateTabAt(
      1, TabStripUserGestureDetails(
             TabStripUserGestureDetails::GestureType::kOther));
  // TODO(crbug.com/11055): It should not be necessary to commit the load here,
  // but because of this bug, it will assert later if we don't. When the bug is
  // fixed, one of the three commits here related to this bug should be removed
  // (to test both codepaths).
  CommitPendingLoad(&first->GetController());
  EXPECT_EQ(1, browser()->tab_strip_model()->active_index());
  chrome::GoForward(browser(), WindowOpenDisposition::NEW_BACKGROUND_TAB);

  // The previous tab should be unchanged and still in the foreground.
  EXPECT_EQ(url1, first->GetLastCommittedURL());
  EXPECT_FALSE(first->GetController().CanGoBack());
  EXPECT_TRUE(first->GetController().CanGoForward());
  EXPECT_EQ(1, browser()->tab_strip_model()->active_index());

  // There should be a new tab navigated forward.
  ASSERT_EQ(3, browser()->tab_strip_model()->count());
  WebContents* second = browser()->tab_strip_model()->GetWebContentsAt(2);
  // Since we didn't wait for load to complete, we can't use
  // GetLastCommittedURL.
  EXPECT_EQ(url2, second->GetVisibleURL());
  EXPECT_TRUE(second->GetController().CanGoBack());
  EXPECT_FALSE(second->GetController().CanGoForward());

  // Now do back in a new foreground tab. Don't bother re-checking every sngle
  // thing above, just validate that it's opening properly.
  browser()->tab_strip_model()->ActivateTabAt(
      2, TabStripUserGestureDetails(
             TabStripUserGestureDetails::GestureType::kOther));
  // TODO(crbug.com/11055): see the comment above about why we need this.
  CommitPendingLoad(&second->GetController());
  chrome::GoBack(browser(), WindowOpenDisposition::NEW_FOREGROUND_TAB);
  ASSERT_EQ(3, browser()->tab_strip_model()->active_index());
  ASSERT_EQ(url1,
            browser()->tab_strip_model()->GetActiveWebContents()->
                GetVisibleURL());

  // Same thing again for forward.
  // TODO(crbug.com/11055): see the comment above about why we need this.
  CommitPendingLoad(&
      browser()->tab_strip_model()->GetActiveWebContents()->GetController());
  chrome::GoForward(browser(), WindowOpenDisposition::NEW_FOREGROUND_TAB);
  ASSERT_EQ(4, browser()->tab_strip_model()->active_index());
  ASSERT_EQ(url2,
            browser()->tab_strip_model()->GetActiveWebContents()->
                GetVisibleURL());
}

// Tests back/forward in new tab (Control + Back/Forward button in the UI)
// with Tab Groups enabled.
TEST_F(BrowserCommandsTest, BackForwardInNewTabWithGroup) {
  GURL url1("http://foo/1");
  GURL url2("http://foo/2");
  ASSERT_TRUE(browser()->tab_strip_model()->SupportsTabGroups());

  // Make a tab with the two pages navigated in it.
  AddTab(browser(), url1);
  NavigateAndCommitActiveTab(url2);

  // Add the tab to a Tab Group.
  const tab_groups::TabGroupId group_id =
      browser()->tab_strip_model()->AddToNewGroup({0});

  // Go back in a new background tab.
  chrome::GoBack(browser(), WindowOpenDisposition::NEW_BACKGROUND_TAB);
  ASSERT_EQ(0, browser()->tab_strip_model()->active_index());
  ASSERT_EQ(2, browser()->tab_strip_model()->count());

  // The new tab should have inherited the tab group from the old tab.
  EXPECT_EQ(group_id, browser()->tab_strip_model()->GetTabGroupForTab(1));

  // Select the second tab and make it go forward in a new background tab.
  browser()->tab_strip_model()->ActivateTabAt(
      1, TabStripUserGestureDetails(
             TabStripUserGestureDetails::GestureType::kOther));
  // TODO(crbug.com/11055): see the comment above about why we need this.
  CommitPendingLoad(
      &browser()->tab_strip_model()->GetActiveWebContents()->GetController());
  chrome::GoForward(browser(), WindowOpenDisposition::NEW_BACKGROUND_TAB);

  // The new tab should have inherited the tab group from the old tab.
  EXPECT_EQ(group_id, browser()->tab_strip_model()->GetTabGroupForTab(2));
}

TEST_F(BrowserCommandsTest, OnMaxZoomIn) {
  TabStripModel* tab_strip_model = browser()->tab_strip_model();

  GURL url("http://www.google.com");
  AddTab(browser(), url);
  WebContents* first_tab = tab_strip_model->GetWebContentsAt(0);

  // Continue to zoom in until zoom percent reaches 500.
  for (int i = 0; i < 9; ++i) {
    zoom::PageZoom::Zoom(first_tab, content::PAGE_ZOOM_IN);
  }

  // TODO(a.sarkar.arun@gmail.com): Figure out why Zoom-In menu item is not
  // disabled after Max-zoom is reached. Force disable Zoom-In menu item
  // from the context menu since it breaks try jobs on bots.
  if (chrome::IsCommandEnabled(browser(), IDC_ZOOM_PLUS))
    chrome::UpdateCommandEnabled(browser(), IDC_ZOOM_PLUS, false);

  ZoomController* zoom_controller = ZoomController::FromWebContents(first_tab);
  EXPECT_FLOAT_EQ(500.0f, zoom_controller->GetZoomPercent());
  EXPECT_FALSE(chrome::IsCommandEnabled(browser(), IDC_ZOOM_PLUS));
  EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_ZOOM_NORMAL));
  EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_ZOOM_MINUS));
}

TEST_F(BrowserCommandsTest, OnMaxZoomOut) {
  TabStripModel* tab_strip_model = browser()->tab_strip_model();

  GURL url("http://www.google.com");
  AddTab(browser(), url);
  WebContents* first_tab = tab_strip_model->GetWebContentsAt(0);

  // Continue to zoom out until zoom percent reaches 25.
  for (int i = 0; i < 7; ++i) {
    zoom::PageZoom::Zoom(first_tab, content::PAGE_ZOOM_OUT);
  }

  ZoomController* zoom_controller = ZoomController::FromWebContents(first_tab);
  EXPECT_FLOAT_EQ(25.0f, zoom_controller->GetZoomPercent());
  EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_ZOOM_PLUS));
  EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_ZOOM_NORMAL));
  EXPECT_FALSE(chrome::IsCommandEnabled(browser(), IDC_ZOOM_MINUS));
}

TEST_F(BrowserCommandsTest, OnZoomReset) {
  TabStripModel* tab_strip_model = browser()->tab_strip_model();

  GURL url("http://www.google.com");
  AddTab(browser(), url);
  WebContents* first_tab = tab_strip_model->GetWebContentsAt(0);

  // Change the zoom percentage to 100.
  zoom::PageZoom::Zoom(first_tab, content::PAGE_ZOOM_RESET);

  ZoomController* zoom_controller = ZoomController::FromWebContents(first_tab);
  EXPECT_FLOAT_EQ(100.0f, zoom_controller->GetZoomPercent());
  EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_ZOOM_PLUS));
  EXPECT_FALSE(chrome::IsCommandEnabled(browser(), IDC_ZOOM_NORMAL));
  EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_ZOOM_MINUS));

  // Changing the page scale factor will re-enable IDC_ZOOM_NORMAL
  zoom_controller->SetPageScaleFactorIsOneForTesting(false);
  EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_ZOOM_NORMAL));
}

TEST_F(BrowserCommandsTest, OnZoomLevelChanged) {
  TabStripModel* tab_strip_model = browser()->tab_strip_model();

  GURL url("http://www.google.com");
  AddTab(browser(), url);
  WebContents* first_tab = tab_strip_model->GetWebContentsAt(0);

  // Changing zoom percentage from default should enable all the zoom
  // NSMenuItems.
  zoom::PageZoom::Zoom(first_tab, content::PAGE_ZOOM_IN);

  ZoomController* zoom_controller = ZoomController::FromWebContents(first_tab);
  EXPECT_FLOAT_EQ(110.0f, zoom_controller->GetZoomPercent());
  EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_ZOOM_PLUS));
  EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_ZOOM_NORMAL));
  EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_ZOOM_MINUS));
}

TEST_F(BrowserCommandsTest, OnZoomChangedForActiveTab) {
  TabStripModel* tab_strip_model = browser()->tab_strip_model();

  GURL url("http://www.google.com");
  GURL url1("http://code.google.com");

  // Add First tab.
  AddTab(browser(), url);
  AddTab(browser(), url1);
  WebContents* first_tab = tab_strip_model->GetWebContentsAt(0);

  ZoomController* zoom_controller = ZoomController::FromWebContents(first_tab);
  EXPECT_FLOAT_EQ(100.0f, zoom_controller->GetZoomPercent());
  EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_ZOOM_PLUS));
  EXPECT_FALSE(chrome::IsCommandEnabled(browser(), IDC_ZOOM_NORMAL));
  EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_ZOOM_MINUS));

  // Add Second tab.
  WebContents* second_tab = tab_strip_model->GetWebContentsAt(1);

  tab_strip_model->ActivateTabAt(
      1, TabStripUserGestureDetails(
             TabStripUserGestureDetails::GestureType::kOther));
  EXPECT_TRUE(tab_strip_model->IsTabSelected(1));
  zoom::PageZoom::Zoom(second_tab, content::PAGE_ZOOM_OUT);

  zoom_controller = ZoomController::FromWebContents(second_tab);
  EXPECT_FLOAT_EQ(90.0f, zoom_controller->GetZoomPercent());
  EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_ZOOM_PLUS));
  EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_ZOOM_NORMAL));
  EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_ZOOM_MINUS));
}

TEST_F(BrowserCommandsTest, OnDefaultZoomLevelChanged) {
  TabStripModel* tab_strip_model = browser()->tab_strip_model();
  GURL url("http://code.google.com");
  AddTab(browser(), url);
  WebContents* tab = tab_strip_model->GetWebContentsAt(0);
  ZoomController* zoom_controller = ZoomController::FromWebContents(tab);

  // Set the default zoom level to 125.
  profile()->GetZoomLevelPrefs()->SetDefaultZoomLevelPref(
      blink::PageZoomFactorToZoomLevel(1.25));
  EXPECT_FLOAT_EQ(125.0f, zoom_controller->GetZoomPercent());

  // Actual Size from context menu should be disabled now.
  EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_ZOOM_PLUS));
  EXPECT_FALSE(chrome::IsCommandEnabled(browser(), IDC_ZOOM_NORMAL));
  EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_ZOOM_MINUS));

  // Change the zoom level.
  zoom::PageZoom::Zoom(tab, content::PAGE_ZOOM_IN);

  EXPECT_FLOAT_EQ(150.0f, zoom_controller->GetZoomPercent());

  // Tab no longer at default zoom hence actual size should be enabled.
  EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_ZOOM_PLUS));
  EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_ZOOM_NORMAL));
  EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_ZOOM_MINUS));
}

TEST_F(BrowserCommandsTest, ToggleCaretBrowsing) {
  // Set initial known state for browser process TestingProfile.
  PrefService* pref_service = profile()->GetPrefs();
  pref_service->SetBoolean(prefs::kCaretBrowsingEnabled, false);
  pref_service->SetBoolean(prefs::kShowCaretBrowsingDialog, false);

#if BUILDFLAG(IS_MAC)
  // On Mac, caret browsing should be disabled unless focus is in web content.
  // Make sure it's disabled initially and doesn't toggle if executed.
  EXPECT_FALSE(chrome::IsCommandEnabled(browser(), IDC_CARET_BROWSING_TOGGLE));
  chrome::ExecuteCommand(browser(), IDC_CARET_BROWSING_TOGGLE);
  EXPECT_FALSE(pref_service->GetBoolean(prefs::kCaretBrowsingEnabled));
#endif

  // Create multiple tabs to test if caret browsing mode gets broadcast to all
  // tabs when toggled. (For the purposes of testing, this simulates
  // putting focus in web contents as a side effect.)
  GURL about_blank(url::kAboutBlankURL);
  int tab_count = 3;
  for (int i = 0; i < tab_count; ++i) {
    AddTab(browser(), about_blank);
  }

  // Toggle on caret browsing.
  EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_CARET_BROWSING_TOGGLE));
  chrome::ExecuteCommand(browser(), IDC_CARET_BROWSING_TOGGLE);
  EXPECT_TRUE(pref_service->GetBoolean(prefs::kCaretBrowsingEnabled));

  // Add another tab after toggling caret browsing mode--it should also have
  // caret browsing mode set.
  AddTab(browser(), about_blank);
  tab_count++;

  // Check renderer preferences for each tab.
  for (int i = 0; i < tab_count; ++i) {
    WebContents* web_contents =
        browser()->tab_strip_model()->GetWebContentsAt(i);
    blink::RendererPreferences* renderer_preferences =
        web_contents->GetMutableRendererPrefs();
    EXPECT_TRUE(renderer_preferences->caret_browsing_enabled);
  }

  // Toggle off caret browsing.
  chrome::ExecuteCommand(browser(), IDC_CARET_BROWSING_TOGGLE);
  EXPECT_FALSE(pref_service->GetBoolean(prefs::kCaretBrowsingEnabled));

  // Add another tab after toggling caret browsing mode--it should also have
  // caret browsing mode unset.
  AddTab(browser(), about_blank);
  tab_count++;

  // Check renderer preferences for each tab.
  for (int i = 0; i < tab_count; ++i) {
    WebContents* web_contents =
        browser()->tab_strip_model()->GetWebContentsAt(i);
    blink::RendererPreferences* renderer_preferences =
        web_contents->GetMutableRendererPrefs();
    EXPECT_FALSE(renderer_preferences->caret_browsing_enabled);
  }
}

TEST_F(BrowserCommandsTest, TabSearchCommandStatus) {
  EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_TAB_SEARCH));
  EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_TAB_SEARCH_CLOSE));
}

}  // namespace
