// Copyright (c) 2012 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 <stddef.h>

#include "base/bind.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
#include "chrome/browser/extensions/extension_browsertest.h"
#include "chrome/browser/extensions/lazy_background_page_test_util.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/renderer_context_menu/render_view_context_menu.h"
#include "chrome/browser/renderer_context_menu/render_view_context_menu_test_util.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/test/base/ui_test_utils.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 "extensions/browser/extension_api_frame_id_map.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/process_manager.h"
#include "extensions/browser/test_management_policy.h"
#include "extensions/common/extension_set.h"
#include "extensions/test/extension_test_message_listener.h"
#include "net/dns/mock_host_resolver.h"
#include "ui/base/models/menu_model.h"

using content::WebContents;
using extensions::ContextMenuMatcher;
using extensions::MenuItem;
using ui::MenuModel;

class ExtensionContextMenuBrowserTest
    : public extensions::ExtensionBrowserTest {
 public:
  // Helper to load an extension from context_menus/|subdirectory| in the
  // extensions test data dir.
  const extensions::Extension* LoadContextMenuExtension(
      std::string subdirectory) {
    base::FilePath extension_dir =
        test_data_dir_.AppendASCII("context_menus").AppendASCII(subdirectory);
    return LoadExtension(extension_dir);
  }

  // Helper to load an extension from context_menus/top_level/|subdirectory| in
  // the extensions test data dir.
  const extensions::Extension* LoadTopLevelContextMenuExtension(
      std::string subdirectory) {
    base::FilePath extension_dir =
        test_data_dir_.AppendASCII("context_menus").AppendASCII("top_level");
    extension_dir = extension_dir.AppendASCII(subdirectory);
    return LoadExtension(extension_dir);
  }

  const extensions::Extension* LoadContextMenuExtensionIncognito(
      std::string subdirectory) {
    base::FilePath extension_dir =
        test_data_dir_.AppendASCII("context_menus").AppendASCII(subdirectory);
    return LoadExtensionIncognito(extension_dir);
  }

  // Returns the active WebContents.
  WebContents* GetWebContents() {
    return browser()->tab_strip_model()->GetActiveWebContents();
  }

  // Shortcut to return the current MenuManager.
  extensions::MenuManager* menu_manager() {
    return extensions::MenuManager::Get(browser()->profile());
  }

  // Returns a pointer to the currently loaded extension with |name|, or null
  // if not found.
  const extensions::Extension* GetExtensionNamed(const std::string& name) {
    const extensions::ExtensionSet& extensions =
        extensions::ExtensionRegistry::Get(
            browser()->profile())->enabled_extensions();
    for (const auto& ext : extensions) {
      if (ext->name() == name)
        return ext.get();
    }
    return nullptr;
  }

  // This gets all the items that any extension has registered for possible
  // inclusion in context menus.
  MenuItem::List GetItems() {
    MenuItem::List result;
    std::set<MenuItem::ExtensionKey> extension_ids =
        menu_manager()->ExtensionIds();
    for (auto i = extension_ids.begin(); i != extension_ids.end(); ++i) {
      const MenuItem::OwnedList* list = menu_manager()->MenuItems(*i);
      for (const auto& item : *list)
        result.push_back(item.get());
    }
    return result;
  }

  // This creates a test menu for a page with |page_url| and |link_url|, looks
  // for an extension item with the given |label|, and returns true if the item
  // was found.
  bool MenuHasItemWithLabel(const GURL& page_url,
                            const GURL& link_url,
                            const GURL& frame_url,
                            const std::string& label) {
    std::unique_ptr<TestRenderViewContextMenu> menu(
        TestRenderViewContextMenu::Create(GetWebContents(), page_url, link_url,
                                          frame_url));
    return MenuHasExtensionItemWithLabel(menu.get(), label);
  }

  // Click on a context menu identified by |target_menu_item_id|, and returns
  // the result of chrome.test.sendMessage. The .js test file that sets up the
  // context menu should call chrome.test.sendMessage in its onclick event.
  std::string ClickMenuInFrame(content::RenderFrameHost* frame,
                               const std::string& target_menu_item_id) {
    content::ContextMenuParams params;
    if (frame->GetParent())
      params.frame_url = frame->GetLastCommittedURL();
    else
      params.page_url = frame->GetLastCommittedURL();

    TestRenderViewContextMenu menu(frame, params);
    menu.Init();

    MenuItem::Id menu_item_id;
    menu_item_id.string_uid = target_menu_item_id;
    int command_id = -1;
    if (!FindCommandId(&menu, menu_item_id, &command_id))
      return "Menu item not found: " + target_menu_item_id;

    ExtensionTestMessageListener listener(false);
    menu.ExecuteCommand(command_id, 0);
    if (!listener.WaitUntilSatisfied())
      return "Onclick never fired for menu item: " + target_menu_item_id;

    return listener.message();
  }

  // This creates an extension that starts |enabled| and then switches to
  // |!enabled|.
  void TestEnabledContextMenu(bool enabled) {
    ExtensionTestMessageListener begin("begin", true);
    ExtensionTestMessageListener create("create", true);
    ExtensionTestMessageListener update("update", false);
    ASSERT_TRUE(LoadContextMenuExtension("enabled"));

    ASSERT_TRUE(begin.WaitUntilSatisfied());

    if (enabled)
      begin.Reply("start enabled");
    else
      begin.Reply("start disabled");

    // Wait for the extension to tell us it's created an item.
    ASSERT_TRUE(create.WaitUntilSatisfied());
    create.Reply("go");

    GURL page_url("http://www.google.com");

    // Create and build our test context menu.
    std::unique_ptr<TestRenderViewContextMenu> menu(
        TestRenderViewContextMenu::Create(GetWebContents(), page_url, GURL(),
                                          GURL()));

    // Look for the extension item in the menu, and make sure it's |enabled|.
    int command_id = ContextMenuMatcher::ConvertToExtensionsCustomCommandId(0);
    ASSERT_EQ(enabled, menu->IsCommandIdEnabled(command_id));

    // Update the item and make sure it is now |!enabled|.
    ASSERT_TRUE(update.WaitUntilSatisfied());
    ASSERT_EQ(!enabled, menu->IsCommandIdEnabled(command_id));
  }

  bool MenuHasExtensionItemWithLabel(TestRenderViewContextMenu* menu,
                                     const std::string& label) {
    base::string16 label16 = base::UTF8ToUTF16(label);
    for (const auto& it : menu->extension_items().extension_item_map_) {
      const MenuItem::Id& id = it.second;
      base::string16 tmp_label;
      EXPECT_TRUE(GetItemLabel(menu, id, &tmp_label));
      if (tmp_label == label16)
        return true;
    }
    return false;
  }

  // Looks in the menu for an extension item with |id|, and if it is found and
  // has a label, that is put in |result| and we return true. Otherwise returns
  // false.
  bool GetItemLabel(TestRenderViewContextMenu* menu,
                    const MenuItem::Id& id,
                    base::string16* result) const {
    int command_id = 0;
    if (!FindCommandId(menu, id, &command_id))
      return false;

    MenuModel* model = nullptr;
    int index = -1;
    if (!menu->GetMenuModelAndItemIndex(command_id, &model, &index)) {
      return false;
    }
    *result = model->GetLabelAt(index);
    return true;
  }

  // Given an extension menu item id, tries to find the corresponding command id
  // in the menu.
  bool FindCommandId(TestRenderViewContextMenu* menu,
                     const MenuItem::Id& id,
                     int* command_id) const {
    for (const auto& it : menu->extension_items().extension_item_map_) {
      if (it.second == id) {
        *command_id = it.first;
        return true;
      }
    }
    return false;
  }

  // Given a menu item id, executes the item's command.
  void ExecuteCommand(TestRenderViewContextMenu* menu,
                      const extensions::ExtensionId& extension_id,
                      const std::string& item_uid) {
    MenuItem::Id id(false, MenuItem::ExtensionKey(extension_id));
    id.string_uid = item_uid;
    int command_id = -1;
    ASSERT_TRUE(FindCommandId(menu, id, &command_id));
    menu->ExecuteCommand(command_id, 0);
  }

  // Verifies a radio item's selection state (checked or unchecked).
  void VerifyRadioItemSelectionState(
      TestRenderViewContextMenu* menu,
      const extensions::ExtensionId& extension_id,
      const std::string& radio_uid,
      bool should_be_checked) {
    MenuItem::Id id(false, MenuItem::ExtensionKey(extension_id));
    id.string_uid = radio_uid;
    int command_id = -1;
    ASSERT_TRUE(FindCommandId(menu, id, &command_id));
    EXPECT_EQ(should_be_checked, menu->IsCommandIdChecked(command_id));
  }
};

// Tests adding a simple context menu item.
IN_PROC_BROWSER_TEST_F(ExtensionContextMenuBrowserTest, Simple) {
  ExtensionTestMessageListener listener1("created item", false);
  ExtensionTestMessageListener listener2("onclick fired", false);
  ASSERT_TRUE(LoadContextMenuExtension("simple"));

  // Wait for the extension to tell us it's created an item.
  ASSERT_TRUE(listener1.WaitUntilSatisfied());

  GURL page_url("http://www.google.com");

  // Create and build our test context menu.
  std::unique_ptr<TestRenderViewContextMenu> menu(
      TestRenderViewContextMenu::Create(GetWebContents(), page_url, GURL(),
                                        GURL()));

  // Look for the extension item in the menu, and execute it.
  int command_id = ContextMenuMatcher::ConvertToExtensionsCustomCommandId(0);
  ASSERT_TRUE(menu->IsCommandIdEnabled(command_id));
  menu->ExecuteCommand(command_id, 0);

  // Wait for the extension's script to tell us its onclick fired.
  ASSERT_TRUE(listener2.WaitUntilSatisfied());
}

// Tests that previous onclick is not fired after updating the menu's onclick,
// and whether setting onclick to null removes the handler.
IN_PROC_BROWSER_TEST_F(ExtensionContextMenuBrowserTest, UpdateOnclick) {
  ExtensionTestMessageListener listener_error1("onclick1-unexpected", false);
  ExtensionTestMessageListener listener_error2("onclick2-unexpected", false);
  ExtensionTestMessageListener listener_update1("update1", true);
  ExtensionTestMessageListener listener_update2("update2", false);
  ExtensionTestMessageListener listener_done("onclick2", false);

  const extensions::Extension* extension =
      LoadContextMenuExtension("onclick_null");
  ASSERT_TRUE(extension);

  // Wait till item has been created and updated.
  ASSERT_TRUE(listener_update1.WaitUntilSatisfied());

  GURL page_url("http://www.google.com");

  // Create and build our test context menu.
  std::unique_ptr<TestRenderViewContextMenu> menu(
      TestRenderViewContextMenu::Create(GetWebContents(), page_url, GURL(),
                                        GURL()));

  // Look for the extension item in the menu, and execute it.
  MenuItem::Id id(false, MenuItem::ExtensionKey(extension->id()));
  id.string_uid = "id1";
  int command_id = -1;
  ASSERT_TRUE(FindCommandId(menu.get(), id, &command_id));
  menu->ExecuteCommand(command_id, 0);

  // Let the test proceed.
  listener_update1.Reply("");

  // Wait until the second context menu has been set up.
  ASSERT_TRUE(listener_update2.WaitUntilSatisfied());

  // Rebuild the context menu and click on the second extension item.
  menu = TestRenderViewContextMenu::Create(GetWebContents(), page_url, GURL(),
                                           GURL());
  id.string_uid = "id2";
  ASSERT_TRUE(FindCommandId(menu.get(), id, &command_id));
  menu->ExecuteCommand(command_id, 0);
  ASSERT_TRUE(listener_done.WaitUntilSatisfied());

  // Upon completion, the replaced onclick callbacks should not have fired.
  ASSERT_FALSE(listener_error1.was_satisfied());
  ASSERT_FALSE(listener_error2.was_satisfied());
}

// Tests that updating the first radio item in a radio list from checked to
// unchecked should not work. The radio button should remain checked because
// context menu radio lists should always have one item selected.
IN_PROC_BROWSER_TEST_F(ExtensionContextMenuBrowserTest,
                       UpdateCheckedStateOfFirstRadioItem) {
  ExtensionTestMessageListener listener_created_radio1("created radio1 item",
                                                       false);
  ExtensionTestMessageListener listener_created_radio2("created radio2 item",
                                                       false);
  ExtensionTestMessageListener listener_created_item1("created normal item",
                                                      false);
  ExtensionTestMessageListener listener_created_item2(
      "created second normal item", false);

  ExtensionTestMessageListener listener_radio2_clicked("onclick radio2", false);
  ExtensionTestMessageListener listener_item1_clicked("onclick normal item",
                                                      false);
  ExtensionTestMessageListener listener_radio1_updated("radio1 updated", false);

  const extensions::Extension* extension =
      LoadContextMenuExtension("radio_check");
  ASSERT_TRUE(extension);

  // Check that all menu items are created.
  ASSERT_TRUE(listener_created_radio1.WaitUntilSatisfied());
  ASSERT_TRUE(listener_created_radio2.WaitUntilSatisfied());
  ASSERT_TRUE(listener_created_item1.WaitUntilSatisfied());
  ASSERT_TRUE(listener_created_item2.WaitUntilSatisfied());

  GURL page_url("http://www.google.com");

  // Create and build our test context menu.
  std::unique_ptr<TestRenderViewContextMenu> menu(
      TestRenderViewContextMenu::Create(GetWebContents(), page_url, GURL(),
                                        GURL()));

  VerifyRadioItemSelectionState(menu.get(), extension->id(), "radio1", true);
  VerifyRadioItemSelectionState(menu.get(), extension->id(), "radio2", false);

  // Clicking the regular item calls chrome.contextMenus.update to uncheck the
  // first radio item.
  ExecuteCommand(menu.get(), extension->id(), "item1");
  ASSERT_TRUE(listener_item1_clicked.WaitUntilSatisfied());

  // Unchecking the second item should not deselect it. Recall that context menu
  // radio lists should always have one item selected.
  ASSERT_TRUE(listener_radio1_updated.WaitUntilSatisfied());
  VerifyRadioItemSelectionState(menu.get(), extension->id(), "radio1", true);
  VerifyRadioItemSelectionState(menu.get(), extension->id(), "radio2", false);
}

// Tests that updating a checked radio button (that is not the first item) to be
// unchecked should not work. The radio button should remain checked because
// context menu radio lists should always have one item selected.
IN_PROC_BROWSER_TEST_F(ExtensionContextMenuBrowserTest,
                       UpdateCheckedStateOfNonfirstRadioItem) {
  ExtensionTestMessageListener listener_created_radio1("created radio1 item",
                                                       false);
  ExtensionTestMessageListener listener_created_radio2("created radio2 item",
                                                       false);
  ExtensionTestMessageListener listener_created_item1("created normal item",
                                                      false);
  ExtensionTestMessageListener listener_created_item2(
      "created second normal item", false);

  ExtensionTestMessageListener listener_radio2_clicked("onclick radio2", false);
  ExtensionTestMessageListener listener_item2_clicked(
      "onclick second normal item", false);
  ExtensionTestMessageListener listener_radio2_updated("radio2 updated", false);

  const extensions::Extension* extension =
      LoadContextMenuExtension("radio_check");
  ASSERT_TRUE(extension);

  // Check that all menu items are created.
  ASSERT_TRUE(listener_created_radio1.WaitUntilSatisfied());
  ASSERT_TRUE(listener_created_radio2.WaitUntilSatisfied());
  ASSERT_TRUE(listener_created_item1.WaitUntilSatisfied());

  ASSERT_TRUE(listener_created_item2.WaitUntilSatisfied());

  GURL page_url("http://www.google.com");

  // Create and build our test context menu.
  std::unique_ptr<TestRenderViewContextMenu> menu(
      TestRenderViewContextMenu::Create(GetWebContents(), page_url, GURL(),
                                        GURL()));

  VerifyRadioItemSelectionState(menu.get(), extension->id(), "radio1", true);
  VerifyRadioItemSelectionState(menu.get(), extension->id(), "radio2", false);

  // Click on the second radio button. This should uncheck the first radio item
  // and check the second item.
  ExecuteCommand(menu.get(), extension->id(), "radio2");
  ASSERT_TRUE(listener_radio2_clicked.WaitUntilSatisfied());
  VerifyRadioItemSelectionState(menu.get(), extension->id(), "radio1", false);
  VerifyRadioItemSelectionState(menu.get(), extension->id(), "radio2", true);

  // Clicking the regular item calls chrome.contextMenus.update to uncheck the
  // second radio item.
  ExecuteCommand(menu.get(), extension->id(), "item2");
  ASSERT_TRUE(listener_item2_clicked.WaitUntilSatisfied());

  // Unchecking the second item should not deselect it. Recall that context menu
  // radio lists should always have one item selected.
  ASSERT_TRUE(listener_radio2_updated.WaitUntilSatisfied());
  VerifyRadioItemSelectionState(menu.get(), extension->id(), "radio1", false);
  VerifyRadioItemSelectionState(menu.get(), extension->id(), "radio2", true);
}

// Tests that setting "documentUrlPatterns" for an item properly restricts
// those items to matching pages.
IN_PROC_BROWSER_TEST_F(ExtensionContextMenuBrowserTest, Patterns) {
  ExtensionTestMessageListener listener("created items", false);

  ASSERT_TRUE(LoadContextMenuExtension("patterns"));

  // Wait for the js test code to create its two items with patterns.
  ASSERT_TRUE(listener.WaitUntilSatisfied());

  // Check that a document url that should match the items' patterns appears.
  GURL google_url("http://www.google.com");
  ASSERT_TRUE(MenuHasItemWithLabel(google_url,
                                   GURL(),
                                   GURL(),
                                   std::string("test_item1")));
  ASSERT_TRUE(MenuHasItemWithLabel(google_url,
                                   GURL(),
                                   GURL(),
                                   std::string("test_item2")));

  // Now check with a non-matching url.
  GURL test_url("http://www.test.com");
  ASSERT_FALSE(MenuHasItemWithLabel(test_url,
                                    GURL(),
                                   GURL(),
                                    std::string("test_item1")));
  ASSERT_FALSE(MenuHasItemWithLabel(test_url,
                                    GURL(),
                                    GURL(),
                                    std::string("test_item2")));
}

// Tests registering an item with a very long title that should get truncated in
// the actual menu displayed.
IN_PROC_BROWSER_TEST_F(ExtensionContextMenuBrowserTest, LongTitle) {
  ExtensionTestMessageListener listener("created", false);

  // Load the extension and wait until it's created a menu item.
  ASSERT_TRUE(LoadContextMenuExtension("long_title"));
  ASSERT_TRUE(listener.WaitUntilSatisfied());

  // Make sure we have an item registered with a long title.
  size_t limit = extensions::ContextMenuMatcher::kMaxExtensionItemTitleLength;
  MenuItem::List items = GetItems();
  ASSERT_EQ(1u, items.size());
  MenuItem* item = items.at(0);
  ASSERT_GT(item->title().size(), limit);

  // Create a context menu, then find the item's label. It should be properly
  // truncated.
  GURL url("http://foo.com/");
  std::unique_ptr<TestRenderViewContextMenu> menu(
      TestRenderViewContextMenu::Create(GetWebContents(), url, GURL(), GURL()));

  base::string16 label;
  ASSERT_TRUE(GetItemLabel(menu.get(), item->id(), &label));
  ASSERT_TRUE(label.size() <= limit);
}

// Flaky on Windows debug bots. http://crbug.com/251590
#if defined(OS_WIN)
#define MAYBE_TopLevel DISABLED_TopLevel
#else
#define MAYBE_TopLevel TopLevel
#endif
// Checks that Context Menus are ordered alphabetically by their name when
// extensions have only one single Context Menu item and by the extension name
// when multiples Context Menu items are created.
IN_PROC_BROWSER_TEST_F(ExtensionContextMenuBrowserTest, MAYBE_TopLevel) {
  // We expect to see the following items in the menu:
  //   An Extension with multiple Context Menus
  //     Context Menu #1
  //     Context Menu #2
  //   Context Menu #1 - Extension #2
  //   Context Menu #2 - Extension #3
  //   Context Menu #3 - Extension #1
  //   Ze Extension with multiple Context Menus
  //     Context Menu #1
  //     Context Menu #2

  // Load extensions and wait until it's created a single menu item.
  ExtensionTestMessageListener listener1("created item", false);
  ASSERT_TRUE(LoadTopLevelContextMenuExtension("single1"));
  ASSERT_TRUE(listener1.WaitUntilSatisfied());

  ExtensionTestMessageListener listener2("created item", false);
  ASSERT_TRUE(LoadTopLevelContextMenuExtension("single2"));
  ASSERT_TRUE(listener2.WaitUntilSatisfied());

  ExtensionTestMessageListener listener3("created item", false);
  ASSERT_TRUE(LoadTopLevelContextMenuExtension("single3"));
  ASSERT_TRUE(listener3.WaitUntilSatisfied());

  // Load extensions and wait until it's created two menu items.
  ExtensionTestMessageListener listener4("created items", false);
  ASSERT_TRUE(LoadTopLevelContextMenuExtension("multi4"));
  ASSERT_TRUE(listener4.WaitUntilSatisfied());

  ExtensionTestMessageListener listener5("created items", false);
  ASSERT_TRUE(LoadTopLevelContextMenuExtension("multi5"));
  ASSERT_TRUE(listener5.WaitUntilSatisfied());

  GURL url("http://foo.com/");
  std::unique_ptr<TestRenderViewContextMenu> menu(
      TestRenderViewContextMenu::Create(GetWebContents(), url, GURL(), GURL()));

  int index = 0;
  MenuModel* model = nullptr;

  ASSERT_TRUE(menu->GetMenuModelAndItemIndex(
      ContextMenuMatcher::ConvertToExtensionsCustomCommandId(0),
      &model,
      &index));
  EXPECT_EQ(base::UTF8ToUTF16("An Extension with multiple Context Menus"),
                              model->GetLabelAt(index++));
  EXPECT_EQ(base::UTF8ToUTF16("Context Menu #1 - Extension #2"),
                              model->GetLabelAt(index++));
  EXPECT_EQ(base::UTF8ToUTF16("Context Menu #2 - Extension #3"),
                              model->GetLabelAt(index++));
  EXPECT_EQ(base::UTF8ToUTF16("Context Menu #3 - Extension #1"),
                              model->GetLabelAt(index++));
  EXPECT_EQ(base::UTF8ToUTF16("Ze Extension with multiple Context Menus"),
                              model->GetLabelAt(index++));
}

// Checks that in |menu|, the item at |index| has type |expected_type| and a
// label of |expected_label|.
static void ExpectLabelAndType(const char* expected_label,
                               MenuModel::ItemType expected_type,
                               const MenuModel& menu,
                               int index) {
  EXPECT_EQ(expected_type, menu.GetTypeAt(index));
  EXPECT_EQ(base::UTF8ToUTF16(expected_label), menu.GetLabelAt(index));
}

// In the separators test we build a submenu with items and separators in two
// different ways - this is used to verify the results in both cases. Separators
// are not included on OS_CHROMEOS.
static void VerifyMenuForSeparatorsTest(const MenuModel& menu) {
  // We expect to see the following items in the menu:
  //  radio1
  //  radio2
  //  --separator-- (automatically added)
  //  normal1
  //  --separator--
  //  normal2
  //  --separator--
  //  radio3
  //  radio4
  //  --separator--
  //  normal3

  int index = 0;
#if defined(OS_CHROMEOS)
  ASSERT_EQ(7, menu.GetItemCount());
#else
  ASSERT_EQ(11, menu.GetItemCount());
#endif  // OS_CHROMEOS
  ExpectLabelAndType("radio1", MenuModel::TYPE_RADIO, menu, index++);
  ExpectLabelAndType("radio2", MenuModel::TYPE_RADIO, menu, index++);
#if !defined(OS_CHROMEOS)
  EXPECT_EQ(MenuModel::TYPE_SEPARATOR, menu.GetTypeAt(index++));
#endif  // !OS_CHROMEOS
  ExpectLabelAndType("normal1", MenuModel::TYPE_COMMAND, menu, index++);
#if !defined(OS_CHROMEOS)
  EXPECT_EQ(MenuModel::TYPE_SEPARATOR, menu.GetTypeAt(index++));
#endif  // !OS_CHROMEOS
  ExpectLabelAndType("normal2", MenuModel::TYPE_COMMAND, menu, index++);
#if !defined(OS_CHROMEOS)
  EXPECT_EQ(MenuModel::TYPE_SEPARATOR, menu.GetTypeAt(index++));
#endif  // !OS_CHROMEOS
  ExpectLabelAndType("radio3", MenuModel::TYPE_RADIO, menu, index++);
  ExpectLabelAndType("radio4", MenuModel::TYPE_RADIO, menu, index++);
#if !defined(OS_CHROMEOS)
  EXPECT_EQ(MenuModel::TYPE_SEPARATOR, menu.GetTypeAt(index++));
#endif  // !OS_CHROMEOS
  ExpectLabelAndType("normal3", MenuModel::TYPE_COMMAND, menu, index++);
}

#if defined(OS_WIN)
#define MAYBE_Separators DISABLED_Separators
#else
#define MAYBE_Separators Separators
#endif

// Tests a number of cases for auto-generated and explicitly added separators.
IN_PROC_BROWSER_TEST_F(ExtensionContextMenuBrowserTest, Separators) {
  // Load the extension.
  ASSERT_TRUE(LoadContextMenuExtension("separators"));
  const extensions::Extension* extension = GetExtensionNamed("Separators Test");
  ASSERT_TRUE(extension);

  // Navigate to test1.html inside the extension, which should create a bunch
  // of items at the top-level (but they'll get pushed into an auto-generated
  // parent).
  ExtensionTestMessageListener listener1("test1 create finished", false);
  ui_test_utils::NavigateToURL(browser(),
                               GURL(extension->GetResourceURL("test1.html")));
  EXPECT_TRUE(listener1.WaitUntilSatisfied());

  GURL url("http://www.google.com/");
  std::unique_ptr<TestRenderViewContextMenu> menu(
      TestRenderViewContextMenu::Create(GetWebContents(), url, GURL(), GURL()));

  // The top-level item should be an "automagic parent" with the extension's
  // name.
  MenuModel* model = nullptr;
  int index = 0;
  base::string16 label;
  ASSERT_TRUE(menu->GetMenuModelAndItemIndex(
      ContextMenuMatcher::ConvertToExtensionsCustomCommandId(0),
      &model,
      &index));
  EXPECT_EQ(base::UTF8ToUTF16(extension->name()), model->GetLabelAt(index));
  ASSERT_EQ(MenuModel::TYPE_SUBMENU, model->GetTypeAt(index));

  // Get the submenu and verify the items there.
  MenuModel* submenu = model->GetSubmenuModelAt(index);
  ASSERT_TRUE(submenu);
  VerifyMenuForSeparatorsTest(*submenu);

  // Now run our second test - navigate to test2.html which creates an explicit
  // parent node and populates that with the same items as in test1.
  ExtensionTestMessageListener listener2("test2 create finished", false);
  ui_test_utils::NavigateToURL(browser(),
                               GURL(extension->GetResourceURL("test2.html")));
  EXPECT_TRUE(listener2.WaitUntilSatisfied());
  menu =
      TestRenderViewContextMenu::Create(GetWebContents(), url, GURL(), GURL());
  ASSERT_TRUE(menu->GetMenuModelAndItemIndex(
      ContextMenuMatcher::ConvertToExtensionsCustomCommandId(0),
      &model,
      &index));
  EXPECT_EQ(base::UTF8ToUTF16("parent"), model->GetLabelAt(index));
  submenu = model->GetSubmenuModelAt(index);
  ASSERT_TRUE(submenu);
  VerifyMenuForSeparatorsTest(*submenu);
}

// Tests that targetUrlPattern keeps items from appearing when there is no
// target url.
IN_PROC_BROWSER_TEST_F(ExtensionContextMenuBrowserTest, TargetURLs) {
  ExtensionTestMessageListener listener("created items", false);
  ASSERT_TRUE(LoadContextMenuExtension("target_urls"));
  ASSERT_TRUE(listener.WaitUntilSatisfied());

  GURL google_url("http://www.google.com");
  GURL non_google_url("http://www.foo.com");

  // No target url - the item should not appear.
  ASSERT_FALSE(MenuHasItemWithLabel(
      google_url, GURL(), GURL(), std::string("item1")));

  // A matching target url - the item should appear.
  ASSERT_TRUE(MenuHasItemWithLabel(google_url,
                                   google_url,
                                   GURL(),
                                   std::string("item1")));

  // A non-matching target url - the item should not appear.
  ASSERT_FALSE(MenuHasItemWithLabel(google_url,
                                    non_google_url,
                                    GURL(),
                                    std::string("item1")));
}

// Tests adding of context menus in incognito mode.
#if defined(OS_LINUX)
// Flakily hangs on Linux/CrOS - http://crbug.com/88317
#define MAYBE_IncognitoSplit DISABLED_IncognitoSplit
#else
#define MAYBE_IncognitoSplit IncognitoSplit
#endif
IN_PROC_BROWSER_TEST_F(ExtensionContextMenuBrowserTest, MAYBE_IncognitoSplit) {
  ExtensionTestMessageListener created("created item regular", false);
  ExtensionTestMessageListener created_incognito("created item incognito",
                                                 false);

  ExtensionTestMessageListener onclick("onclick fired regular", false);
  ExtensionTestMessageListener onclick_incognito("onclick fired incognito",
                                                 false);

  // Open an incognito window.
  Browser* browser_incognito =
      OpenURLOffTheRecord(browser()->profile(), GURL("about:blank"));

  ASSERT_TRUE(LoadContextMenuExtensionIncognito("incognito"));

  // Wait for the extension's processes to tell us they've created an item.
  ASSERT_TRUE(created.WaitUntilSatisfied());
  ASSERT_TRUE(created_incognito.WaitUntilSatisfied());

  GURL page_url("http://www.google.com");

  // Create and build our test context menu.
  std::unique_ptr<TestRenderViewContextMenu> menu(
      TestRenderViewContextMenu::Create(GetWebContents(), page_url, GURL(),
                                        GURL()));
  WebContents* incognito_web_contents =
      browser_incognito->tab_strip_model()->GetActiveWebContents();
  std::unique_ptr<TestRenderViewContextMenu> menu_incognito(
      TestRenderViewContextMenu::Create(incognito_web_contents, page_url,
                                        GURL(), GURL()));

  // Look for the extension item in the menu, and execute it.
  int command_id = ContextMenuMatcher::ConvertToExtensionsCustomCommandId(0);
  ASSERT_TRUE(menu->IsCommandIdEnabled(command_id));
  menu->ExecuteCommand(command_id, 0);

  // Wait for the extension's script to tell us its onclick fired. Ensure
  // that the incognito version doesn't fire until we explicitly click the
  // incognito menu item.
  ASSERT_TRUE(onclick.WaitUntilSatisfied());
  EXPECT_FALSE(onclick_incognito.was_satisfied());

  ASSERT_TRUE(menu_incognito->IsCommandIdEnabled(command_id));
  menu_incognito->ExecuteCommand(command_id, 0);
  ASSERT_TRUE(onclick_incognito.WaitUntilSatisfied());
}

// Tests that items with a context of frames only appear when the menu is
// invoked in a frame.
IN_PROC_BROWSER_TEST_F(ExtensionContextMenuBrowserTest, Frames) {
  ExtensionTestMessageListener listener("created items", false);
  ASSERT_TRUE(LoadContextMenuExtension("frames"));
  ASSERT_TRUE(listener.WaitUntilSatisfied());

  GURL page_url("http://www.google.com");
  GURL no_frame_url;
  GURL frame_url("http://www.google.com");

  ASSERT_TRUE(MenuHasItemWithLabel(
      page_url, GURL(), no_frame_url, std::string("Page item")));
  ASSERT_FALSE(MenuHasItemWithLabel(
      page_url, GURL(), no_frame_url, std::string("Frame item")));

  ASSERT_TRUE(MenuHasItemWithLabel(
      page_url, GURL(), frame_url, std::string("Page item")));
  ASSERT_TRUE(MenuHasItemWithLabel(
      page_url, GURL(), frame_url, std::string("Frame item")));
}

// Tests that info.frameId is correctly set when the context menu is invoked.
IN_PROC_BROWSER_TEST_F(ExtensionContextMenuBrowserTest, ClickInFrame) {
  ExtensionTestMessageListener listener("created items", false);
  ASSERT_TRUE(LoadContextMenuExtension("frames"));
  GURL url_with_frame("data:text/html,<iframe name='child'>");
  ui_test_utils::NavigateToURL(browser(), url_with_frame);
  ASSERT_TRUE(listener.WaitUntilSatisfied());

  // Click on a menu item in the main frame.
  EXPECT_EQ(
      "pageUrl=" + url_with_frame.spec() + ", frameUrl=undefined, frameId=0",
      ClickMenuInFrame(GetWebContents()->GetMainFrame(), "item1"));

  // Click on a menu item in the child frame.
  content::RenderFrameHost* child_frame = content::FrameMatchingPredicate(
      GetWebContents(), base::Bind(&content::FrameMatchesName, "child"));
  ASSERT_TRUE(child_frame);
  int extension_api_frame_id =
      extensions::ExtensionApiFrameIdMap::GetFrameId(child_frame);
  EXPECT_EQ(
      base::StringPrintf("pageUrl=undefined, frameUrl=about:blank, frameId=%d",
                         extension_api_frame_id),
      ClickMenuInFrame(child_frame, "item1"));
}

// Tests enabling and disabling a context menu item.
IN_PROC_BROWSER_TEST_F(ExtensionContextMenuBrowserTest, Enabled) {
  TestEnabledContextMenu(true);
  TestEnabledContextMenu(false);
}

class ExtensionContextMenuBrowserLazyTest :
    public ExtensionContextMenuBrowserTest {
  void SetUpOnMainThread() override {
    ExtensionContextMenuBrowserTest::SetUpOnMainThread();
    // Set shorter delays to prevent test timeouts.
    extensions::ProcessManager::SetEventPageIdleTimeForTesting(1);
    extensions::ProcessManager::SetEventPageSuspendingTimeForTesting(0);
  }
};

IN_PROC_BROWSER_TEST_F(ExtensionContextMenuBrowserLazyTest, EventPage) {
  GURL about_blank("about:blank");
  LazyBackgroundObserver page_complete;
  const extensions::Extension* extension = LoadContextMenuExtension(
      "event_page");
  ASSERT_TRUE(extension);
  page_complete.Wait();

  // Test that menu items appear while the page is unloaded.
  ASSERT_TRUE(MenuHasItemWithLabel(
      about_blank, GURL(), GURL(), std::string("Item 1")));
  ASSERT_TRUE(MenuHasItemWithLabel(
      about_blank, GURL(), GURL(), std::string("Checkbox 1")));

  // Test that checked menu items retain their checkedness.
  LazyBackgroundObserver checkbox_checked;
  std::unique_ptr<TestRenderViewContextMenu> menu(
      TestRenderViewContextMenu::Create(GetWebContents(), about_blank, GURL(),
                                        GURL()));

  MenuItem::Id id(false, MenuItem::ExtensionKey(extension->id()));
  id.string_uid = "checkbox1";
  int command_id = -1;
  ASSERT_TRUE(FindCommandId(menu.get(), id, &command_id));
  EXPECT_FALSE(menu->IsCommandIdChecked(command_id));

  // Executing the checkbox also fires the onClicked event.
  ExtensionTestMessageListener listener("onClicked fired for checkbox1", false);
  menu->ExecuteCommand(command_id, 0);
  checkbox_checked.WaitUntilClosed();

  EXPECT_TRUE(menu->IsCommandIdChecked(command_id));
  ASSERT_TRUE(listener.WaitUntilSatisfied());
}

IN_PROC_BROWSER_TEST_F(ExtensionContextMenuBrowserTest,
                       IncognitoSplitContextMenuCount) {
  ExtensionTestMessageListener created("created item regular", false);
  ExtensionTestMessageListener created_incognito("created item incognito",
                                                 false);

  // Create an incognito profile.
  ASSERT_TRUE(browser()->profile()->GetOffTheRecordProfile());
  ASSERT_TRUE(LoadContextMenuExtensionIncognito("incognito"));

  // Wait for the extension's processes to tell us they've created an item.
  ASSERT_TRUE(created.WaitUntilSatisfied());
  ASSERT_TRUE(created_incognito.WaitUntilSatisfied());
  ASSERT_EQ(2u, GetItems().size());

  browser()->profile()->DestroyOffTheRecordProfile();
  ASSERT_EQ(1u, GetItems().size());
}

// Tests updating checkboxes' checked state to true and false.
IN_PROC_BROWSER_TEST_F(ExtensionContextMenuBrowserTest, UpdateCheckboxes) {
  ExtensionTestMessageListener listener_context_menu_created("Menu created",
                                                             false);

  const extensions::Extension* extension =
      LoadContextMenuExtension("checkboxes");
  ASSERT_TRUE(extension);

  ASSERT_TRUE(listener_context_menu_created.WaitUntilSatisfied());

  GURL page_url("http://www.google.com");

  // Create and build our test context menu.
  std::unique_ptr<TestRenderViewContextMenu> menu(
      TestRenderViewContextMenu::Create(GetWebContents(), page_url, GURL(),
                                        GURL()));

  VerifyRadioItemSelectionState(menu.get(), extension->id(), "checkbox1",
                                false);
  VerifyRadioItemSelectionState(menu.get(), extension->id(), "checkbox2", true);

  ExtensionTestMessageListener listener_item1_clicked("onclick normal item",
                                                      false);
  ExtensionTestMessageListener listener_unchecked_checkbox2(
      "checkbox2 unchecked", false);
  // Clicking the regular item calls chrome.contextMenus.update to uncheck the
  // second checkbox item.
  ExecuteCommand(menu.get(), extension->id(), "item1");
  ASSERT_TRUE(listener_item1_clicked.WaitUntilSatisfied());
  ASSERT_TRUE(listener_unchecked_checkbox2.WaitUntilSatisfied());

  VerifyRadioItemSelectionState(menu.get(), extension->id(), "checkbox1",
                                false);
  VerifyRadioItemSelectionState(menu.get(), extension->id(), "checkbox2",
                                false);
}
