// 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 "chrome/browser/ui/views/tabs/tab_strip.h"

#include <string>

#include "base/bind.h"
#include "base/macros.h"
#include "base/timer/timer.h"
#include "chrome/browser/ui/layout_constants.h"
#include "chrome/browser/ui/views/tabs/fake_base_tab_strip_controller.h"
#include "chrome/browser/ui/views/tabs/new_tab_button.h"
#include "chrome/browser/ui/views/tabs/tab.h"
#include "chrome/browser/ui/views/tabs/tab_group_header.h"
#include "chrome/browser/ui/views/tabs/tab_icon.h"
#include "chrome/browser/ui/views/tabs/tab_renderer_data.h"
#include "chrome/browser/ui/views/tabs/tab_strip_controller.h"
#include "chrome/browser/ui/views/tabs/tab_strip_observer.h"
#include "chrome/browser/ui/views/tabs/tab_style_views.h"
#include "chrome/test/base/testing_profile.h"
#include "chrome/test/views/chrome_views_test_base.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/material_design/material_design_controller.h"
#include "ui/base/test/material_design_controller_test_api.h"
#include "ui/events/base_event_utils.h"
#include "ui/gfx/animation/animation_test_api.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/geometry/rect_conversions.h"
#include "ui/gfx/skia_util.h"
#include "ui/views/accessibility/ax_event_manager.h"
#include "ui/views/accessibility/ax_event_observer.h"
#include "ui/views/accessibility/view_accessibility.h"
#include "ui/views/controls/label.h"
#include "ui/views/view.h"
#include "ui/views/view_targeter.h"
#include "ui/views/widget/widget.h"

namespace {

// Walks up the views hierarchy until it finds a tab view. It returns the
// found tab view, on NULL if none is found.
views::View* FindTabView(views::View* view) {
  views::View* current = view;
  while (current && strcmp(current->GetClassName(), Tab::kViewClassName)) {
    current = current->parent();
  }
  return current;
}

class TestAXEventObserver : public views::AXEventObserver {
 public:
  TestAXEventObserver() { views::AXEventManager::Get()->AddObserver(this); }

  ~TestAXEventObserver() override {
    views::AXEventManager::Get()->RemoveObserver(this);
  }

  // views::AXEventObserver:
  void OnViewEvent(views::View* view, ax::mojom::Event event_type) override {
    if (event_type == ax::mojom::Event::kSelectionRemove) {
      remove_count_++;
    }
    if (event_type == ax::mojom::Event::kSelection) {
      change_count_++;
    }
    if (event_type == ax::mojom::Event::kSelectionAdd) {
      add_count_++;
    }
  }

  int add_count() { return add_count_; }
  int change_count() { return change_count_; }
  int remove_count() { return remove_count_; }

 private:
  int add_count_ = 0;
  int change_count_ = 0;
  int remove_count_ = 0;

  DISALLOW_COPY_AND_ASSIGN(TestAXEventObserver);
};

}  // namespace

class TestTabStripObserver : public TabStripObserver {
 public:
  explicit TestTabStripObserver(TabStrip* tab_strip) : tab_strip_(tab_strip) {
    tab_strip_->AddObserver(this);
  }

  ~TestTabStripObserver() override { tab_strip_->RemoveObserver(this); }

  int last_tab_added() const { return last_tab_added_; }
  int last_tab_removed() const { return last_tab_removed_; }
  int last_tab_moved_from() const { return last_tab_moved_from_; }
  int last_tab_moved_to() const { return last_tab_moved_to_; }

 private:
  // TabStripObserver overrides.
  void OnTabAdded(int index) override { last_tab_added_ = index; }

  void OnTabMoved(int from_index, int to_index) override {
    last_tab_moved_from_ = from_index;
    last_tab_moved_to_ = to_index;
  }

  void OnTabRemoved(int index) override { last_tab_removed_ = index; }

  TabStrip* tab_strip_;
  int last_tab_added_ = -1;
  int last_tab_removed_ = -1;
  int last_tab_moved_from_ = -1;
  int last_tab_moved_to_ = -1;

  DISALLOW_COPY_AND_ASSIGN(TestTabStripObserver);
};

class TabStripTest : public ChromeViewsTestBase,
                     public testing::WithParamInterface<bool> {
 public:
  TabStripTest()
      : test_api_(GetParam()),
        animation_mode_reset_(gfx::AnimationTestApi::SetRichAnimationRenderMode(
            gfx::Animation::RichAnimationRenderMode::FORCE_ENABLED)) {}

  ~TabStripTest() override {}

  void SetUp() override {
    ChromeViewsTestBase::SetUp();

    controller_ = new FakeBaseTabStripController;
    tab_strip_ = new TabStrip(std::unique_ptr<TabStripController>(controller_));
    controller_->set_tab_strip(tab_strip_);
    // Do this to force TabStrip to create the buttons.
    auto* parent = new views::View;
    parent->AddChildView(tab_strip_);

    widget_.reset(new views::Widget);
    views::Widget::InitParams init_params =
        CreateParams(views::Widget::InitParams::TYPE_POPUP);
    init_params.ownership =
        views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
    init_params.bounds = gfx::Rect(0, 0, 200, 200);
    widget_->Init(init_params);
    widget_->SetContentsView(parent);
  }

  void TearDown() override {
    widget_.reset();
    ChromeViewsTestBase::TearDown();
  }

 protected:
  bool IsShowingAttentionIndicator(Tab* tab) {
    return tab->icon_->ShowingAttentionIndicator();
  }

  // Checks whether |tab| contains |point_in_tabstrip_coords|, where the point
  // is in |tab_strip_| coordinates.
  bool IsPointInTab(Tab* tab, const gfx::Point& point_in_tabstrip_coords) {
    gfx::Point point_in_tab_coords(point_in_tabstrip_coords);
    views::View::ConvertPointToTarget(tab_strip_, tab, &point_in_tab_coords);
    return tab->HitTestPoint(point_in_tab_coords);
  }

  Tab* FindTabForEvent(const gfx::Point& point) {
    return tab_strip_->FindTabForEvent(point);
  }

  void DoLayout() { tab_strip_->DoLayout(); }

  void AnimateToIdealBounds() { tab_strip_->AnimateToIdealBounds(); }

  const StackedTabStripLayout* touch_layout() const {
    return tab_strip_->touch_layout_.get();
  }

  views::BoundsAnimator* bounds_animator() {
    return &tab_strip_->bounds_animator_;
  }

  int GetInactiveTabWidth() { return tab_strip_->GetInactiveTabWidth(); }

  // End any outstanding drag and animate tabs back to their ideal bounds.
  void StopDraggingTab(Tab* tab) {
    // Passing false for |is_first_tab| results in running the post-drag
    // animation unconditionally.
    bool is_first_tab = false;
    tab_strip_->StoppedDraggingTab(tab, &is_first_tab);
  }

  // Makes sure that all tabs have the correct AX indices.
  void VerifyTabIndices() {
    for (int i = 0; i < tab_strip_->tab_count(); ++i) {
      ui::AXNodeData ax_node_data;
      tab_strip_->tab_at(i)->GetViewAccessibility().GetAccessibleNodeData(
          &ax_node_data);
      EXPECT_EQ(i + 1, ax_node_data.GetIntAttribute(
                           ax::mojom::IntAttribute::kPosInSet));
      EXPECT_EQ(
          tab_strip_->tab_count(),
          ax_node_data.GetIntAttribute(ax::mojom::IntAttribute::kSetSize));
    }
  }

  std::vector<TabGroupHeader*> ListGroupHeaders() const {
    std::vector<TabGroupHeader*> result;
    for (auto const& header_pair : tab_strip_->group_headers_)
      result.push_back(header_pair.second.get());
    return result;
  }

  // Owned by TabStrip.
  FakeBaseTabStripController* controller_ = nullptr;
  TabStrip* tab_strip_ = nullptr;
  std::unique_ptr<views::Widget> widget_;

  ui::MouseEvent dummy_event_ = ui::MouseEvent(ui::ET_MOUSE_PRESSED,
                                               gfx::PointF(),
                                               gfx::PointF(),
                                               base::TimeTicks::Now(),
                                               0,
                                               0);

 private:
  ui::test::MaterialDesignControllerTestAPI test_api_;
  std::unique_ptr<base::AutoReset<gfx::Animation::RichAnimationRenderMode>>
      animation_mode_reset_;

  DISALLOW_COPY_AND_ASSIGN(TabStripTest);
};

TEST_P(TabStripTest, GetModelCount) {
  EXPECT_EQ(0, tab_strip_->GetModelCount());
}

TEST_P(TabStripTest, AccessibilityEvents) {
  TestAXEventObserver observer;

  // When adding tabs, SetSelection() is called after AddTabAt(), as
  // otherwise the index would not be meaningful.
  tab_strip_->AddTabAt(0, TabRendererData(), false);
  tab_strip_->AddTabAt(1, TabRendererData(), true);
  ui::ListSelectionModel selection;
  selection.SetSelectedIndex(1);
  tab_strip_->SetSelection(selection);
  EXPECT_EQ(0, observer.add_count());
  EXPECT_EQ(1, observer.change_count());
  EXPECT_EQ(0, observer.remove_count());

  // When removing tabs, SetSelection() is called before RemoveTabAt(), as
  // otherwise the index would not be meaningful.
  selection.SetSelectedIndex(0);
  tab_strip_->SetSelection(selection);
  tab_strip_->RemoveTabAt(nullptr, 1, true);
  EXPECT_EQ(0, observer.add_count());
  EXPECT_EQ(2, observer.change_count());
  EXPECT_EQ(0, observer.remove_count());

  // When activating widget, refire selection event on tab.
  widget_->OnNativeWidgetActivationChanged(true);
  EXPECT_EQ(0, observer.add_count());
  EXPECT_EQ(3, observer.change_count());
  EXPECT_EQ(0, observer.remove_count());
}

TEST_P(TabStripTest, AccessibilityData) {
  // When adding tabs, indexes should be set.
  tab_strip_->AddTabAt(0, TabRendererData(), false);
  tab_strip_->AddTabAt(1, TabRendererData(), true);
  VerifyTabIndices();

  tab_strip_->AddTabAt(0, TabRendererData(), false);
  VerifyTabIndices();

  tab_strip_->RemoveTabAt(nullptr, 1, false);
  VerifyTabIndices();

  tab_strip_->MoveTab(1, 0, TabRendererData());
  VerifyTabIndices();
}

TEST_P(TabStripTest, IsValidModelIndex) {
  EXPECT_FALSE(tab_strip_->IsValidModelIndex(0));
}

TEST_P(TabStripTest, tab_count) {
  EXPECT_EQ(0, tab_strip_->tab_count());
}

TEST_P(TabStripTest, AddTabAt) {
  TestTabStripObserver observer(tab_strip_);
  tab_strip_->AddTabAt(0, TabRendererData(), false);
  ASSERT_EQ(1, tab_strip_->tab_count());
  EXPECT_EQ(0, observer.last_tab_added());
  Tab* tab = tab_strip_->tab_at(0);
  EXPECT_FALSE(tab == NULL);
}

TEST_P(TabStripTest, MoveTab) {
  TestTabStripObserver observer(tab_strip_);
  tab_strip_->AddTabAt(0, TabRendererData(), false);
  tab_strip_->AddTabAt(1, TabRendererData(), false);
  tab_strip_->AddTabAt(2, TabRendererData(), false);
  ASSERT_EQ(3, tab_strip_->tab_count());
  EXPECT_EQ(2, observer.last_tab_added());
  Tab* tab = tab_strip_->tab_at(0);
  tab_strip_->MoveTab(0, 1, TabRendererData());
  EXPECT_EQ(0, observer.last_tab_moved_from());
  EXPECT_EQ(1, observer.last_tab_moved_to());
  EXPECT_EQ(tab, tab_strip_->tab_at(1));
}

// Verifies child views are deleted after an animation completes.
TEST_P(TabStripTest, RemoveTab) {
  TestTabStripObserver observer(tab_strip_);
  controller_->AddTab(0, false);
  controller_->AddTab(1, false);
  const size_t num_children = tab_strip_->children().size();
  EXPECT_EQ(2, tab_strip_->tab_count());
  controller_->RemoveTab(0);
  EXPECT_EQ(0, observer.last_tab_removed());
  // When removing a tab the tabcount should immediately decrement.
  EXPECT_EQ(1, tab_strip_->tab_count());
  // But the number of views should remain the same (it's animatining closed).
  EXPECT_EQ(num_children, tab_strip_->children().size());
  tab_strip_->SetBounds(0, 0, 200, 20);
  // Layout at a different size should force the animation to end and delete
  // the tab that was removed.
  tab_strip_->Layout();
  EXPECT_EQ(num_children - 1, tab_strip_->children().size());

  // Remove the last tab to make sure things are cleaned up correctly when
  // the TabStrip is destroyed and an animation is ongoing.
  controller_->RemoveTab(0);
  EXPECT_EQ(0, observer.last_tab_removed());
}

namespace {

bool TabViewsInOrder(TabStrip* tab_strip) {
  for (int i = 1; i < tab_strip->tab_count(); ++i) {
    Tab* left = tab_strip->tab_at(i - 1);
    Tab* right = tab_strip->tab_at(i);

    if (tab_strip->FindChild(right) < tab_strip->FindChild(left)) {
      return false;
    }
  }

  return true;
}

}  // namespace

// Verifies child view order matches model order.
TEST_P(TabStripTest, TabViewOrder) {
  controller_->AddTab(0, false);
  controller_->AddTab(1, false);
  controller_->AddTab(2, false);
  EXPECT_TRUE(TabViewsInOrder(tab_strip_));

  tab_strip_->MoveTab(0, 1, TabRendererData());
  EXPECT_TRUE(TabViewsInOrder(tab_strip_));
  tab_strip_->MoveTab(1, 2, TabRendererData());
  EXPECT_TRUE(TabViewsInOrder(tab_strip_));
  tab_strip_->MoveTab(1, 0, TabRendererData());
  EXPECT_TRUE(TabViewsInOrder(tab_strip_));
  tab_strip_->MoveTab(0, 2, TabRendererData());
  EXPECT_TRUE(TabViewsInOrder(tab_strip_));
}

TEST_P(TabStripTest, VisibilityInOverflow) {
  constexpr int kInitialWidth = 250;
  tab_strip_->SetBounds(0, 0, kInitialWidth, 20);

  // The first tab added to a reasonable-width strip should be visible.  If we
  // add enough additional tabs, eventually one should be invisible due to
  // overflow.
  int invisible_tab_index = 0;
  for (; invisible_tab_index < 100; ++invisible_tab_index) {
    controller_->AddTab(invisible_tab_index, false);
    if (!tab_strip_->tab_at(invisible_tab_index)->GetVisible())
      break;
  }
  EXPECT_GT(invisible_tab_index, 0);
  EXPECT_LT(invisible_tab_index, 100);

  // The tabs before the invisible tab should still be visible.
  for (int i = 0; i < invisible_tab_index; ++i)
    EXPECT_TRUE(tab_strip_->tab_at(i)->GetVisible());

  // Enlarging the strip should result in the last tab becoming visible.
  tab_strip_->SetBounds(0, 0, kInitialWidth * 2, 20);
  EXPECT_TRUE(tab_strip_->tab_at(invisible_tab_index)->GetVisible());

  // Shrinking it again should re-hide the last tab.
  tab_strip_->SetBounds(0, 0, kInitialWidth, 20);
  EXPECT_FALSE(tab_strip_->tab_at(invisible_tab_index)->GetVisible());

  // Shrinking it still more should make more tabs invisible, though not all.
  // All the invisible tabs should be at the end of the strip.
  tab_strip_->SetBounds(0, 0, kInitialWidth / 2, 20);
  int i = 0;
  for (; i < invisible_tab_index; ++i) {
    if (!tab_strip_->tab_at(i)->GetVisible())
      break;
  }
  ASSERT_GT(i, 0);
  EXPECT_LT(i, invisible_tab_index);
  invisible_tab_index = i;
  for (int i = invisible_tab_index + 1; i < tab_strip_->tab_count(); ++i)
    EXPECT_FALSE(tab_strip_->tab_at(i)->GetVisible());

  // When we're already in overflow, adding tabs at the beginning or end of
  // the strip should not change how many tabs are visible.
  controller_->AddTab(tab_strip_->tab_count(), false);
  EXPECT_TRUE(tab_strip_->tab_at(invisible_tab_index - 1)->GetVisible());
  EXPECT_FALSE(tab_strip_->tab_at(invisible_tab_index)->GetVisible());
  controller_->AddTab(0, false);
  EXPECT_TRUE(tab_strip_->tab_at(invisible_tab_index - 1)->GetVisible());
  EXPECT_FALSE(tab_strip_->tab_at(invisible_tab_index)->GetVisible());

  // If we remove enough tabs, all the tabs should be visible.
  for (int i = tab_strip_->tab_count() - 1; i >= invisible_tab_index; --i)
    controller_->RemoveTab(i);
  EXPECT_TRUE(tab_strip_->tab_at(tab_strip_->tab_count() - 1)->GetVisible());
}

// Creates a tab strip in stacked layout mode and verifies that as we move
// across the strip at the top, middle, and bottom, events will target each tab
// in order.
TEST_P(TabStripTest, TabForEventWhenStacked) {
  tab_strip_->SetBounds(0, 0, 250, GetLayoutConstant(TAB_HEIGHT));

  controller_->AddTab(0, false);
  controller_->AddTab(1, true);
  controller_->AddTab(2, false);
  controller_->AddTab(3, false);
  ASSERT_EQ(4, tab_strip_->tab_count());

  // Switch to stacked layout mode and force a layout to ensure tabs stack.
  tab_strip_->SetStackedLayout(true);
  DoLayout();

  gfx::Point p;
  for (int y : {0, tab_strip_->height() / 2, tab_strip_->height() - 1}) {
    p.set_y(y);
    int previous_tab = -1;
    for (int x = 0; x < tab_strip_->width(); ++x) {
      p.set_x(x);
      int tab = tab_strip_->GetModelIndexOfTab(FindTabForEvent(p));
      if (tab == previous_tab)
        continue;
      if ((tab != -1) || (previous_tab != tab_strip_->tab_count() - 1))
        EXPECT_EQ(previous_tab + 1, tab) << "p = " << p.ToString();
      previous_tab = tab;
    }
  }
}

// Tests that the tab close buttons of non-active tabs are hidden when
// the tabstrip is in stacked tab mode.
TEST_P(TabStripTest, TabCloseButtonVisibilityWhenStacked) {
  // Touch-optimized UI requires a larger width for tabs to show close buttons.
  const bool touch_ui = ui::MaterialDesignController::touch_ui();
  tab_strip_->SetBounds(0, 0, touch_ui ? 442 : 346, 20);
  controller_->AddTab(0, false);
  controller_->AddTab(1, true);
  controller_->AddTab(2, false);
  ASSERT_EQ(3, tab_strip_->tab_count());

  Tab* tab0 = tab_strip_->tab_at(0);
  Tab* tab1 = tab_strip_->tab_at(1);
  ASSERT_TRUE(tab1->IsActive());
  Tab* tab2 = tab_strip_->tab_at(2);

  // Ensure that all tab close buttons are initially visible.
  EXPECT_TRUE(tab0->showing_close_button_);
  EXPECT_TRUE(tab1->showing_close_button_);
  EXPECT_TRUE(tab2->showing_close_button_);

  // Enter stacked layout mode and verify this sets |touch_layout_|.
  ASSERT_FALSE(touch_layout());
  tab_strip_->SetStackedLayout(true);
  ASSERT_TRUE(touch_layout());

  // Only the close button of the active tab should be visible in stacked
  // layout mode.
  EXPECT_FALSE(tab0->showing_close_button_);
  EXPECT_TRUE(tab1->showing_close_button_);
  EXPECT_FALSE(tab2->showing_close_button_);

  // An inactive tab added to the tabstrip should not show
  // its tab close button.
  controller_->AddTab(3, false);
  Tab* tab3 = tab_strip_->tab_at(3);
  EXPECT_FALSE(tab0->showing_close_button_);
  EXPECT_TRUE(tab1->showing_close_button_);
  EXPECT_FALSE(tab2->showing_close_button_);
  EXPECT_FALSE(tab3->showing_close_button_);

  // After switching tabs, the previously-active tab should have its
  // tab close button hidden and the newly-active tab should show
  // its tab close button.
  tab_strip_->SelectTab(tab2, dummy_event_);
  ASSERT_FALSE(tab1->IsActive());
  ASSERT_TRUE(tab2->IsActive());
  EXPECT_FALSE(tab0->showing_close_button_);
  EXPECT_FALSE(tab1->showing_close_button_);
  EXPECT_TRUE(tab2->showing_close_button_);
  EXPECT_FALSE(tab3->showing_close_button_);

  // After closing the active tab, the tab which becomes active should
  // show its tab close button.
  tab_strip_->CloseTab(tab1, CLOSE_TAB_FROM_TOUCH);
  tab1 = nullptr;
  ASSERT_TRUE(tab2->IsActive());
  EXPECT_FALSE(tab0->showing_close_button_);
  EXPECT_TRUE(tab2->showing_close_button_);
  EXPECT_FALSE(tab3->showing_close_button_);

  // All tab close buttons should be shown when disengaging stacked tab mode.
  tab_strip_->SetStackedLayout(false);
  ASSERT_FALSE(touch_layout());
  EXPECT_TRUE(tab0->showing_close_button_);
  EXPECT_TRUE(tab2->showing_close_button_);
  EXPECT_TRUE(tab3->showing_close_button_);
}

// Tests that the tab close buttons of non-active tabs are hidden when
// the tabstrip is not in stacked tab mode and the tab sizes are shrunk
// into small sizes.
TEST_P(TabStripTest, TabCloseButtonVisibilityWhenNotStacked) {
  // Set the tab strip width to be wide enough for three tabs to show all
  // three icons, but not enough for five tabs to show all three icons.
  // Touch-optimized UI requires a larger width for tabs to show close buttons.
  const bool touch_ui = ui::MaterialDesignController::touch_ui();
  tab_strip_->SetBounds(0, 0, touch_ui ? 442 : 346, 20);
  controller_->AddTab(0, false);
  controller_->AddTab(1, true);
  controller_->AddTab(2, false);
  ASSERT_EQ(3, tab_strip_->tab_count());

  Tab* tab0 = tab_strip_->tab_at(0);
  ASSERT_FALSE(tab0->IsActive());
  Tab* tab1 = tab_strip_->tab_at(1);
  ASSERT_TRUE(tab1->IsActive());
  Tab* tab2 = tab_strip_->tab_at(2);
  ASSERT_FALSE(tab2->IsActive());

  // Ensure this is not in stacked layout mode.
  ASSERT_FALSE(touch_layout());

  // Ensure that all tab close buttons are initially visible.
  EXPECT_TRUE(tab0->showing_close_button_);
  EXPECT_TRUE(tab1->showing_close_button_);
  EXPECT_TRUE(tab2->showing_close_button_);

  // Shrink the tab sizes by adding more tabs.
  // An inactive tab added to the tabstrip, now each tab size is not
  // big enough to accomodate 3 icons, so it should not show its
  // tab close button.
  controller_->AddTab(3, false);
  Tab* tab3 = tab_strip_->tab_at(3);
  EXPECT_FALSE(tab3->showing_close_button_);

  // This inactive tab doesn't have alert button, but its favicon and
  // title would be shown.
  EXPECT_TRUE(tab3->showing_icon_);
  EXPECT_FALSE(tab3->showing_alert_indicator_);
  EXPECT_TRUE(tab3->title_->GetVisible());

  // The active tab's close button still shows.
  EXPECT_TRUE(tab1->showing_close_button_);

  // An active tab added to the tabstrip should show its tab close
  // button.
  controller_->AddTab(4, true);
  Tab* tab4 = tab_strip_->tab_at(4);
  ASSERT_TRUE(tab4->IsActive());
  EXPECT_TRUE(tab4->showing_close_button_);

  // The previous active button is now inactive so its close
  // button should not show.
  EXPECT_FALSE(tab1->showing_close_button_);

  // After switching tabs, the previously-active tab should have its
  // tab close button hidden and the newly-active tab should show
  // its tab close button.
  tab_strip_->SelectTab(tab2, dummy_event_);
  ASSERT_FALSE(tab4->IsActive());
  ASSERT_TRUE(tab2->IsActive());
  EXPECT_FALSE(tab0->showing_close_button_);
  EXPECT_FALSE(tab1->showing_close_button_);
  EXPECT_TRUE(tab2->showing_close_button_);
  EXPECT_FALSE(tab3->showing_close_button_);
  EXPECT_FALSE(tab4->showing_close_button_);

  // After closing the active tab, the tab which becomes active should
  // show its tab close button.
  tab_strip_->CloseTab(tab2, CLOSE_TAB_FROM_TOUCH);
  tab2 = nullptr;
  ASSERT_TRUE(tab3->IsActive());
  DoLayout();
  EXPECT_FALSE(tab0->showing_close_button_);
  EXPECT_FALSE(tab1->showing_close_button_);
  EXPECT_TRUE(tab3->showing_close_button_);
  EXPECT_FALSE(tab4->showing_close_button_);
}

TEST_P(TabStripTest, GetEventHandlerForOverlappingArea) {
  tab_strip_->SetBounds(0, 0, 1000, 20);

  controller_->AddTab(0, false);
  controller_->AddTab(1, true);
  controller_->AddTab(2, false);
  controller_->AddTab(3, false);
  ASSERT_EQ(4, tab_strip_->tab_count());

  // Verify that the active tab will be a tooltip handler for points that hit
  // it.
  Tab* left_tab = tab_strip_->tab_at(0);
  left_tab->SetBoundsRect(gfx::Rect(gfx::Point(0, 0), gfx::Size(200, 20)));

  Tab* active_tab = tab_strip_->tab_at(1);
  active_tab->SetBoundsRect(gfx::Rect(gfx::Point(150, 0), gfx::Size(200, 20)));
  ASSERT_TRUE(active_tab->IsActive());

  Tab* right_tab = tab_strip_->tab_at(2);
  right_tab->SetBoundsRect(gfx::Rect(gfx::Point(300, 0), gfx::Size(200, 20)));

  Tab* most_right_tab = tab_strip_->tab_at(3);
  most_right_tab->SetBoundsRect(
      gfx::Rect(gfx::Point(450, 0), gfx::Size(200, 20)));

  // Test that active tabs gets events from area in which it overlaps with its
  // left neighbour.
  gfx::Point left_overlap(
      (active_tab->x() + left_tab->bounds().right() + 1) / 2,
      active_tab->bounds().bottom() - 1);

  // Sanity check that the point is in both active and left tab.
  ASSERT_TRUE(IsPointInTab(active_tab, left_overlap));
  ASSERT_TRUE(IsPointInTab(left_tab, left_overlap));

  EXPECT_EQ(active_tab,
            FindTabView(tab_strip_->GetEventHandlerForPoint(left_overlap)));

  // Test that active tabs gets events from area in which it overlaps with its
  // right neighbour.
  gfx::Point right_overlap((active_tab->bounds().right() + right_tab->x()) / 2,
                           active_tab->bounds().bottom() - 1);

  // Sanity check that the point is in both active and right tab.
  ASSERT_TRUE(IsPointInTab(active_tab, right_overlap));
  ASSERT_TRUE(IsPointInTab(right_tab, right_overlap));

  EXPECT_EQ(active_tab,
            FindTabView(tab_strip_->GetEventHandlerForPoint(right_overlap)));

  // Test that if neither of tabs is active, the left one is selected.
  gfx::Point unactive_overlap(
      (right_tab->x() + most_right_tab->bounds().right() + 1) / 2,
      right_tab->bounds().bottom() - 1);

  // Sanity check that the point is in both active and left tab.
  ASSERT_TRUE(IsPointInTab(right_tab, unactive_overlap));
  ASSERT_TRUE(IsPointInTab(most_right_tab, unactive_overlap));

  EXPECT_EQ(right_tab,
            FindTabView(tab_strip_->GetEventHandlerForPoint(unactive_overlap)));
}

TEST_P(TabStripTest, GetTooltipHandler) {
  tab_strip_->SetBounds(0, 0, 1000, 20);

  controller_->AddTab(0, false);
  controller_->AddTab(1, true);
  controller_->AddTab(2, false);
  controller_->AddTab(3, false);
  ASSERT_EQ(4, tab_strip_->tab_count());

  // Verify that the active tab will be a tooltip handler for points that hit
  // it.
  Tab* left_tab = tab_strip_->tab_at(0);
  left_tab->SetBoundsRect(gfx::Rect(gfx::Point(0, 0), gfx::Size(200, 20)));

  Tab* active_tab = tab_strip_->tab_at(1);
  active_tab->SetBoundsRect(gfx::Rect(gfx::Point(150, 0), gfx::Size(200, 20)));
  ASSERT_TRUE(active_tab->IsActive());

  Tab* right_tab = tab_strip_->tab_at(2);
  right_tab->SetBoundsRect(gfx::Rect(gfx::Point(300, 0), gfx::Size(200, 20)));

  Tab* most_right_tab = tab_strip_->tab_at(3);
  most_right_tab->SetBoundsRect(
      gfx::Rect(gfx::Point(450, 0), gfx::Size(200, 20)));

  // Test that active_tab handles tooltips from area in which it overlaps with
  // its left neighbour.
  gfx::Point left_overlap(
      (active_tab->x() + left_tab->bounds().right() + 1) / 2,
      active_tab->bounds().bottom() - 1);

  // Sanity check that the point is in both active and left tab.
  ASSERT_TRUE(IsPointInTab(active_tab, left_overlap));
  ASSERT_TRUE(IsPointInTab(left_tab, left_overlap));

  EXPECT_EQ(active_tab,
            FindTabView(tab_strip_->GetTooltipHandlerForPoint(left_overlap)));

  // Test that active_tab handles tooltips from area in which it overlaps with
  // its right neighbour.
  gfx::Point right_overlap((active_tab->bounds().right() + right_tab->x()) / 2,
                           active_tab->bounds().bottom() - 1);

  // Sanity check that the point is in both active and right tab.
  ASSERT_TRUE(IsPointInTab(active_tab, right_overlap));
  ASSERT_TRUE(IsPointInTab(right_tab, right_overlap));

  EXPECT_EQ(active_tab,
            FindTabView(tab_strip_->GetTooltipHandlerForPoint(right_overlap)));

  // Test that if neither of tabs is active, the left one is selected.
  gfx::Point unactive_overlap(
      (right_tab->x() + most_right_tab->bounds().right() + 1) / 2,
      right_tab->bounds().bottom() - 1);

  // Sanity check that the point is in both active and left tab.
  ASSERT_TRUE(IsPointInTab(right_tab, unactive_overlap));
  ASSERT_TRUE(IsPointInTab(most_right_tab, unactive_overlap));

  EXPECT_EQ(
      right_tab,
      FindTabView(tab_strip_->GetTooltipHandlerForPoint(unactive_overlap)));

  // Confirm that tab strip doe not return tooltip handler for points that
  // don't hit it.
  EXPECT_FALSE(tab_strip_->GetTooltipHandlerForPoint(gfx::Point(-1, 2)));
}

TEST_P(TabStripTest, NewTabButtonStaysVisible) {
  const int kTabStripWidth = 500;
  tab_strip_->SetBounds(0, 0, kTabStripWidth, 20);

  for (int i = 0; i < 100; ++i)
    controller_->AddTab(i, (i == 0));

  DoLayout();

  EXPECT_LE(tab_strip_->new_tab_button_bounds().right(), kTabStripWidth);
}

// The active tab should always be at least as wide as its minimum width.
// http://crbug.com/587688
TEST_P(TabStripTest, ActiveTabWidthWhenTabsAreTiny) {
  // The bug was caused when it's animating. Therefore we should make widget
  // visible so that animation can be triggered.
  tab_strip_->GetWidget()->Show();
  tab_strip_->SetBounds(0, 0, 200, 20);

  // Create a lot of tabs in order to make inactive tabs tiny.
  const int min_inactive_width = TabStyleViews::GetMinimumInactiveWidth();
  while (GetInactiveTabWidth() != min_inactive_width)
    controller_->CreateNewTab();

  int active_index = controller_->GetActiveIndex();
  EXPECT_GT(tab_strip_->tab_count(), 1);
  EXPECT_EQ(tab_strip_->tab_count() - 1, active_index);
  EXPECT_LT(tab_strip_->ideal_bounds(0).width(),
            tab_strip_->ideal_bounds(active_index).width());

  // During mouse-based tab closure, the active tab should remain at least as
  // wide as it's minimum width.
  controller_->SelectTab(0, dummy_event_);
  while (tab_strip_->tab_count() > 0) {
    const int active_index = controller_->GetActiveIndex();
    EXPECT_GE(tab_strip_->ideal_bounds(active_index).width(),
              TabStyleViews::GetMinimumActiveWidth());
    tab_strip_->CloseTab(tab_strip_->tab_at(active_index),
                         CLOSE_TAB_FROM_MOUSE);
  }
}

// Inactive tabs shouldn't shrink during mouse-based tab closure.
// http://crbug.com/850190
TEST_P(TabStripTest, InactiveTabWidthWhenTabsAreTiny) {
  tab_strip_->SetBounds(0, 0, 200, 20);

  // Create a lot of tabs in order to make inactive tabs smaller than active
  // tab but not the minimum.
  const int min_inactive_width = TabStyleViews::GetMinimumInactiveWidth();
  const int min_active_width = TabStyleViews::GetMinimumActiveWidth();
  while (GetInactiveTabWidth() >= (min_inactive_width + min_active_width) / 2) {
    controller_->CreateNewTab();
  }

  // During mouse-based tab closure, inactive tabs shouldn't shrink
  // so that users can close tabs continuously without moving mouse.
  controller_->SelectTab(0, dummy_event_);
  // If there are only two tabs in the strip, then after closing one the
  // remaining one will be active and there will be no inactive tabs,
  // so we stop at 2.
  while (tab_strip_->tab_count() > 2) {
    const int last_inactive_width = GetInactiveTabWidth();
    tab_strip_->CloseTab(tab_strip_->tab_at(controller_->GetActiveIndex()),
                         CLOSE_TAB_FROM_MOUSE);
    EXPECT_GE(GetInactiveTabWidth(), last_inactive_width);
  }
}

// When dragged tabs are moving back to their position, changes to ideal bounds
// should be respected. http://crbug.com/848016
TEST_P(TabStripTest, ResetBoundsForDraggedTabs) {
  tab_strip_->SetBounds(0, 0, 200, 20);

  // Create a lot of tabs in order to make inactive tabs tiny.
  const int min_inactive_width = TabStyleViews::GetMinimumInactiveWidth();
  while (GetInactiveTabWidth() != min_inactive_width)
    controller_->CreateNewTab();

  const int min_active_width = TabStyleViews::GetMinimumActiveWidth();

  int dragged_tab_index = controller_->GetActiveIndex();
  EXPECT_GE(tab_strip_->ideal_bounds(dragged_tab_index).width(),
            min_active_width);

  // Mark the active tab as being dragged.
  Tab* dragged_tab = tab_strip_->tab_at(dragged_tab_index);
  dragged_tab->set_dragging(true);

  gfx::AnimationContainerTestApi test_api(bounds_animator()->container());

  // Ending the drag triggers the tabstrip to begin animating this tab back
  // to its ideal bounds.
  StopDraggingTab(dragged_tab);
  EXPECT_TRUE(bounds_animator()->IsAnimating(dragged_tab));

  // Change the ideal bounds of the tabs mid-animation by selecting a
  // different tab.
  controller_->SelectTab(0, dummy_event_);

  // Once the animation completes, the dragged tab should have animated to
  // the new ideal bounds (computed with this as an inactive tab) rather
  // than the original ones (where it's an active tab).
  const auto duration = base::TimeDelta::FromMilliseconds(
      bounds_animator()->GetAnimationDuration());
  test_api.IncrementTime(duration);

  EXPECT_FALSE(dragged_tab->dragging());
  EXPECT_LT(dragged_tab->bounds().width(), min_active_width);
}

// The "blocked" attention indicator should only show for background tabs.
TEST_P(TabStripTest, TabNeedsAttentionBlocked) {
  controller_->AddTab(0, false);
  controller_->AddTab(1, true);

  Tab* tab1 = tab_strip_->tab_at(1);

  // Block tab1.
  TabRendererData data;
  data.blocked = true;
  tab1->SetData(data);

  EXPECT_FALSE(IsShowingAttentionIndicator(tab1));
  controller_->SelectTab(0, dummy_event_);
  EXPECT_TRUE(IsShowingAttentionIndicator(tab1));
  controller_->SelectTab(1, dummy_event_);
  EXPECT_FALSE(IsShowingAttentionIndicator(tab1));
}

// The generic "wants attention" version should always show.
TEST_P(TabStripTest, TabNeedsAttentionGeneric) {
  controller_->AddTab(0, false);
  controller_->AddTab(1, true);

  Tab* tab1 = tab_strip_->tab_at(1);

  tab1->SetTabNeedsAttention(true);

  EXPECT_TRUE(IsShowingAttentionIndicator(tab1));
  controller_->SelectTab(0, dummy_event_);
  EXPECT_TRUE(IsShowingAttentionIndicator(tab1));
  controller_->SelectTab(1, dummy_event_);
  EXPECT_TRUE(IsShowingAttentionIndicator(tab1));
}

TEST_P(TabStripTest, NewTabButtonInkDrop) {
  constexpr int kTabStripWidth = 500;
  tab_strip_->SetBounds(0, 0, kTabStripWidth, GetLayoutConstant(TAB_HEIGHT));

  // Add a few tabs and simulate the new tab button's ink drop animation. This
  // should not cause any crashes since the ink drop layer size as well as the
  // ink drop container size should remain equal to the new tab button visible
  // bounds size. https://crbug.com/814105.
  for (int i = 0; i < 10; ++i) {
    tab_strip_->new_tab_button()->AnimateInkDropToStateForTesting(
        views::InkDropState::ACTION_TRIGGERED);
    controller_->AddTab(i, true /* is_active */);
    DoLayout();
    tab_strip_->new_tab_button()->AnimateInkDropToStateForTesting(
        views::InkDropState::HIDDEN);
  }
}

// Closing tab should be targeted during event dispatching.
TEST_P(TabStripTest, EventsOnClosingTab) {
  tab_strip_->SetBounds(0, 0, 200, 20);

  controller_->AddTab(0, false);
  controller_->AddTab(1, true);

  Tab* first_tab = tab_strip_->tab_at(0);
  gfx::Point tab_center = first_tab->bounds().CenterPoint();

  EXPECT_EQ(first_tab, tab_strip_->GetEventHandlerForPoint(tab_center));
  tab_strip_->CloseTab(first_tab, CLOSE_TAB_FROM_MOUSE);
  EXPECT_EQ(first_tab, tab_strip_->GetEventHandlerForPoint(tab_center));
}

// Switch selected tabs on horizontal scroll events.
TEST_P(TabStripTest, HorizontalScroll) {
  tab_strip_->SetBounds(0, 0, 200, 20);

  for (int i = 0; i < 3; i++)
    controller_->AddTab(i, true /* is_active */);

  Tab* tab = tab_strip_->tab_at(0);
  gfx::Point tab_center = tab->bounds().CenterPoint();

  for (int i = 0; i < tab_strip_->tab_count(); ++i) {
    ui::MouseWheelEvent wheel_event(
        gfx::Vector2d(ui::MouseWheelEvent::kWheelDelta, 0), tab_center,
        tab_center, ui::EventTimeForNow(), 0, 0);
    tab_strip_->OnMouseWheel(wheel_event);
    EXPECT_EQ(i, controller_->GetActiveIndex());
  }

  controller_->SelectTab(0, dummy_event_);
  for (int i = tab_strip_->tab_count() - 1; i >= 0; --i) {
    ui::MouseWheelEvent wheel_event(
        gfx::Vector2d(-ui::MouseWheelEvent::kWheelDelta, 0), tab_center,
        tab_center, ui::EventTimeForNow(), 0, 0);
    tab_strip_->OnMouseWheel(wheel_event);
    EXPECT_EQ(i, controller_->GetActiveIndex());
  }

  // When offset is smaller than kWheelDelta, we don't scroll immediately.
  // We wait offset until accumulated offset gets bigger than kWheelDelta.
  const int small_offset = ui::MouseWheelEvent::kWheelDelta / 3;
  int next_accumulated_offset = small_offset;
  while (next_accumulated_offset < ui::MouseWheelEvent::kWheelDelta) {
    ui::MouseWheelEvent wheel_event(gfx::Vector2d(small_offset, 0), tab_center,
                                    tab_center, ui::EventTimeForNow(), 0, 0);
    tab_strip_->OnMouseWheel(wheel_event);

    EXPECT_EQ(0, controller_->GetActiveIndex());
    next_accumulated_offset += small_offset;
  }

  ui::MouseWheelEvent wheel_event(gfx::Vector2d(small_offset, 0), tab_center,
                                  tab_center, ui::EventTimeForNow(), 0, 0);
  tab_strip_->OnMouseWheel(wheel_event);
  EXPECT_EQ(1, controller_->GetActiveIndex());
}

TEST_P(TabStripTest, GroupHeaderBasics) {
  tab_strip_->SetBounds(0, 0, 1000, 100);
  bounds_animator()->SetAnimationDuration(0);
  tab_strip_->AddTabAt(0, TabRendererData(), false);

  Tab* tab = tab_strip_->tab_at(0);
  const int first_slot_x = tab->x();

  base::Optional<int> group = controller_->CreateTabGroup();
  controller_->MoveTabIntoGroup(0, group);

  std::vector<TabGroupHeader*> headers = ListGroupHeaders();
  EXPECT_EQ(1u, headers.size());
  TabGroupHeader* header = headers[0];
  EXPECT_EQ(first_slot_x, header->x());
  EXPECT_EQ(tab->width(), header->width());
  EXPECT_EQ(tab->height(), header->height());
}

TEST_P(TabStripTest, GroupHeaderBetweenTabs) {
  tab_strip_->SetBounds(0, 0, 1000, 100);
  bounds_animator()->SetAnimationDuration(0);

  tab_strip_->AddTabAt(0, TabRendererData(), false);
  tab_strip_->AddTabAt(1, TabRendererData(), false);

  const int second_slot_x = tab_strip_->tab_at(1)->x();

  base::Optional<int> group = controller_->CreateTabGroup();
  controller_->MoveTabIntoGroup(1, group);

  TabGroupHeader* header = ListGroupHeaders()[0];
  EXPECT_EQ(header->x(), second_slot_x);
}

// This can happen when a tab in the middle of a group starts to close.
TEST_P(TabStripTest, DiscontinuousGroup) {
  tab_strip_->SetBounds(0, 0, 1000, 100);
  bounds_animator()->SetAnimationDuration(0);

  tab_strip_->AddTabAt(0, TabRendererData(), false);
  tab_strip_->AddTabAt(1, TabRendererData(), false);
  tab_strip_->AddTabAt(2, TabRendererData(), false);

  const int first_slot_x = tab_strip_->tab_at(0)->x();

  base::Optional<int> group = controller_->CreateTabGroup();
  controller_->MoveTabIntoGroup(0, group);
  controller_->MoveTabIntoGroup(2, group);

  std::vector<TabGroupHeader*> headers = ListGroupHeaders();
  EXPECT_EQ(1u, headers.size());
  EXPECT_EQ(first_slot_x, headers[0]->x());
}

TEST_P(TabStripTest, DeleteTabGroupHeaderWhenEmpty) {
  tab_strip_->AddTabAt(0, TabRendererData(), false);
  tab_strip_->AddTabAt(1, TabRendererData(), false);
  base::Optional<int> group = controller_->CreateTabGroup();
  controller_->MoveTabIntoGroup(0, group);
  controller_->MoveTabIntoGroup(1, group);
  controller_->MoveTabIntoGroup(0, base::nullopt);

  EXPECT_EQ(1u, ListGroupHeaders().size());
  controller_->MoveTabIntoGroup(1, base::nullopt);
  EXPECT_EQ(0u, ListGroupHeaders().size());
}

INSTANTIATE_TEST_SUITE_P(, TabStripTest, ::testing::Values(false, true));
