// Copyright (c) 2011 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/strings/utf_string_conversions.h"
#include "content/common/frame_messages.h"
#include "content/public/test/render_view_test.h"
#include "content/renderer/render_frame_impl.h"
#include "content/renderer/render_view_impl.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/WebKit/public/web/WebView.h"
#include "third_party/WebKit/public/platform/WebSize.h"

// Tests for the external select popup menu (Mac specific).

namespace content {
namespace {

const char* const kSelectID = "mySelect";
const char* const kEmptySelectID = "myEmptySelect";

}  // namespace

class ExternalPopupMenuTest : public RenderViewTest {
 public:
  ExternalPopupMenuTest() {}

  RenderViewImpl* view() {
    return static_cast<RenderViewImpl*>(view_);
  }

  RenderFrameImpl* frame() {
    return view()->GetMainRenderFrame();
  }

  void SetUp() override {
    RenderViewTest::SetUp();
    // We need to set this explictly as RenderMain is not run.
    blink::WebView::setUseExternalPopupMenus(true);

    std::string html = "<select id='mySelect' onchange='selectChanged(this)'>"
                       "  <option>zero</option>"
                       "  <option selected='1'>one</option>"
                       "  <option>two</option>"
                       "</select>"
                       "<select id='myEmptySelect'>"
                       "</select>";
    if (ShouldRemoveSelectOnChange()) {
      html += "<script>"
              "  function selectChanged(select) {"
              "    select.parentNode.removeChild(select);"
              "  }"
              "</script>";
    }

    // Load the test page.
    LoadHTML(html.c_str());

    // Set a minimum size and give focus so simulated events work.
    view()->webwidget()->resize(blink::WebSize(500, 500));
    view()->webwidget()->setFocus(true);
  }

  int GetSelectedIndex() {
    base::string16 script(base::ASCIIToUTF16(kSelectID));
    script.append(base::ASCIIToUTF16(".selectedIndex"));
    int selected_index = -1;
    ExecuteJavaScriptAndReturnIntValue(script, &selected_index);
    return selected_index;
  }

 protected:
  virtual bool ShouldRemoveSelectOnChange() const { return false; }

  DISALLOW_COPY_AND_ASSIGN(ExternalPopupMenuTest);
};

// Normal case: test showing a select popup, canceling/selecting an item.
TEST_F(ExternalPopupMenuTest, NormalCase) {
  IPC::TestSink& sink = render_thread_->sink();

  // Click the text field once.
  EXPECT_TRUE(SimulateElementClick(kSelectID));

  // We should have sent a message to the browser to show the popup menu.
  const IPC::Message* message =
      sink.GetUniqueMessageMatching(FrameHostMsg_ShowPopup::ID);
  ASSERT_TRUE(message != NULL);
  base::Tuple<FrameHostMsg_ShowPopup_Params> param;
  FrameHostMsg_ShowPopup::Read(message, &param);
  ASSERT_EQ(3U, base::get<0>(param).popup_items.size());
  EXPECT_EQ(1, base::get<0>(param).selected_item);

  // Simulate the user canceling the popup; the index should not have changed.
  frame()->OnSelectPopupMenuItem(-1);
  EXPECT_EQ(1, GetSelectedIndex());

  // Show the pop-up again and this time make a selection.
  EXPECT_TRUE(SimulateElementClick(kSelectID));
  frame()->OnSelectPopupMenuItem(0);
  EXPECT_EQ(0, GetSelectedIndex());

  // Show the pop-up again and make another selection.
  sink.ClearMessages();
  EXPECT_TRUE(SimulateElementClick(kSelectID));
  message = sink.GetUniqueMessageMatching(FrameHostMsg_ShowPopup::ID);
  ASSERT_TRUE(message != NULL);
  FrameHostMsg_ShowPopup::Read(message, &param);
  ASSERT_EQ(3U, base::get<0>(param).popup_items.size());
  EXPECT_EQ(0, base::get<0>(param).selected_item);
}

// Page shows popup, then navigates away while popup showing, then select.
TEST_F(ExternalPopupMenuTest, ShowPopupThenNavigate) {
  // Click the text field once.
  EXPECT_TRUE(SimulateElementClick(kSelectID));

  // Now we navigate to another pager.
  LoadHTML("<blink>Awesome page!</blink>");

  // Now the user selects something, we should not crash.
  frame()->OnSelectPopupMenuItem(-1);
}

// An empty select should not cause a crash when clicked.
// http://crbug.com/63774
TEST_F(ExternalPopupMenuTest, EmptySelect) {
  EXPECT_TRUE(SimulateElementClick(kEmptySelectID));
}

class ExternalPopupMenuRemoveTest : public ExternalPopupMenuTest {
 public:
  ExternalPopupMenuRemoveTest() {}

 protected:
  bool ShouldRemoveSelectOnChange() const override { return true; }
};

// Tests that nothing bad happen when the page removes the select when it
// changes. (http://crbug.com/61997)
TEST_F(ExternalPopupMenuRemoveTest, RemoveOnChange) {
  // Click the text field once to show the popup.
  EXPECT_TRUE(SimulateElementClick(kSelectID));

  // Select something, it causes the select to be removed from the page.
  frame()->OnSelectPopupMenuItem(0);

  // Just to check the soundness of the test, call SimulateElementClick again.
  // It should return false as the select has been removed.
  EXPECT_FALSE(SimulateElementClick(kSelectID));
}

class ExternalPopupMenuDisplayNoneTest : public ExternalPopupMenuTest {
  public:
  ExternalPopupMenuDisplayNoneTest() {}

  void SetUp() override {
    RenderViewTest::SetUp();
    // We need to set this explictly as RenderMain is not run.
    blink::WebView::setUseExternalPopupMenus(true);

    std::string html = "<select id='mySelect'>"
                       "  <option value='zero'>zero</option>"
                       "  <optgroup label='hide' style='display: none'>"
                       "    <option value='one'>one</option>"
                       "  </optgroup>"
                       "  <option value='two'>two</option>"
                       "  <option value='three'>three</option>"
                       "  <option value='four'>four</option>"
                       "  <option value='five'>five</option>"
                       "</select>";
    // Load the test page.
    LoadHTML(html.c_str());

    // Set a minimum size and give focus so simulated events work.
    view()->webwidget()->resize(blink::WebSize(500, 500));
    view()->webwidget()->setFocus(true);
  }

};

TEST_F(ExternalPopupMenuDisplayNoneTest, SelectItem) {
  IPC::TestSink& sink = render_thread_->sink();

  // Click the text field once to show the popup.
  EXPECT_TRUE(SimulateElementClick(kSelectID));

  // Read the message sent to browser to show the popup menu.
  const IPC::Message* message =
      sink.GetUniqueMessageMatching(FrameHostMsg_ShowPopup::ID);
  ASSERT_TRUE(message != NULL);
  base::Tuple<FrameHostMsg_ShowPopup_Params> param;
  FrameHostMsg_ShowPopup::Read(message, &param);
  // Number of items should match item count minus the number
  // of "display: none" items.
  ASSERT_EQ(5U, base::get<0>(param).popup_items.size());

  // Select index 1 item. This should select item with index 2,
  // skipping the item with 'display: none'
  frame()->OnSelectPopupMenuItem(1);

  EXPECT_EQ(2, GetSelectedIndex());
}

}  // namespace content
