// 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 "ui/views/bubble/bubble_frame_view.h"

#include <memory>

#include "base/macros.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "ui/events/base_event_utils.h"
#include "ui/events/event.h"
#include "ui/gfx/geometry/insets.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/text_utils.h"
#include "ui/views/bubble/bubble_border.h"
#include "ui/views/bubble/bubble_dialog_delegate_view.h"
#include "ui/views/bubble/footnote_container_view.h"
#include "ui/views/controls/button/label_button.h"
#include "ui/views/metrics.h"
#include "ui/views/test/test_layout_provider.h"
#include "ui/views/test/test_views.h"
#include "ui/views/test/views_test_base.h"
#include "ui/views/widget/widget.h"
#include "ui/views/widget/widget_delegate.h"

namespace views {

using BubbleFrameViewTest = ViewsTestBase;

namespace {

const BubbleBorder::Arrow kArrow = BubbleBorder::TOP_LEFT;
const SkColor kColor = SK_ColorRED;
const int kMargin = 6;
const int kMinimumClientWidth = 100;
const int kMinimumClientHeight = 200;
const int kMaximumClientWidth = 300;
const int kMaximumClientHeight = 300;
const int kPreferredClientWidth = 150;
const int kPreferredClientHeight = 250;

// These account for non-client areas like the title bar, footnote etc. However
// these do not take the bubble border into consideration.
const int kExpectedAdditionalWidth = 12;
const int kExpectedAdditionalHeight = 12;

class TestBubbleFrameViewWidgetDelegate : public WidgetDelegate {
 public:
  explicit TestBubbleFrameViewWidgetDelegate(Widget* widget)
      : widget_(widget) {}

  ~TestBubbleFrameViewWidgetDelegate() override = default;

  // WidgetDelegate overrides:
  Widget* GetWidget() override { return widget_; }
  const Widget* GetWidget() const override { return widget_; }

  View* GetContentsView() override {
    if (!contents_view_) {
      StaticSizedView* contents_view = new StaticSizedView(
          gfx::Size(kPreferredClientWidth, kPreferredClientHeight));
      contents_view->set_minimum_size(
          gfx::Size(kMinimumClientWidth, kMinimumClientHeight));
      contents_view->set_maximum_size(
          gfx::Size(kMaximumClientWidth, kMaximumClientHeight));
      contents_view_ = contents_view;
    }
    return contents_view_;
  }

  bool ShouldShowCloseButton() const override { return should_show_close_; }
  void SetShouldShowCloseButton(bool should_show_close) {
    should_show_close_ = should_show_close;
  }

 private:
  Widget* const widget_;
  View* contents_view_ = nullptr;  // Owned by |widget_|.
  bool should_show_close_ = false;
};

class TestBubbleFrameView : public BubbleFrameView {
 public:
  explicit TestBubbleFrameView(ViewsTestBase* test_base)
      : BubbleFrameView(gfx::Insets(), gfx::Insets(kMargin)) {
    SetBubbleBorder(std::make_unique<BubbleBorder>(
        kArrow, BubbleBorder::BIG_SHADOW, kColor));
    widget_ = std::make_unique<Widget>();
    widget_delegate_ =
        std::make_unique<TestBubbleFrameViewWidgetDelegate>(widget_.get());
    Widget::InitParams params =
        test_base->CreateParams(Widget::InitParams::TYPE_BUBBLE);
    params.delegate = widget_delegate_.get();
    params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
    widget_->Init(params);
  }
  ~TestBubbleFrameView() override = default;

  void SetAvailableAnchorWindowBounds(gfx::Rect bounds) {
    available_anchor_window_bounds_ = bounds;
  }

  BubbleBorder::Arrow GetBorderArrow() const {
    return bubble_border_for_testing()->arrow();
  }

  SkColor GetBorderBackgroundColor() const {
    return bubble_border_for_testing()->background_color();
  }

  gfx::Insets GetBorderInsets() const {
    return bubble_border_for_testing()->GetInsets();
  }

  // View overrides:
  const Widget* GetWidget() const override {
    return widget_.get();
  }

  // BubbleFrameView overrides:
  gfx::Rect GetAvailableScreenBounds(const gfx::Rect& rect) const override {
    return available_bounds_;
  }

  gfx::Rect GetAvailableAnchorWindowBounds() const override {
    return available_anchor_window_bounds_;
  }

  TestBubbleFrameViewWidgetDelegate* widget_delegate() {
    return widget_delegate_.get();
  }

 private:
  const gfx::Rect available_bounds_ = gfx::Rect(0, 0, 1000, 1000);
  gfx::Rect available_anchor_window_bounds_;

  std::unique_ptr<TestBubbleFrameViewWidgetDelegate> widget_delegate_;
  std::unique_ptr<Widget> widget_;

  DISALLOW_COPY_AND_ASSIGN(TestBubbleFrameView);
};

}  // namespace

TEST_F(BubbleFrameViewTest, GetBoundsForClientView) {
  TestBubbleFrameView frame(this);
  EXPECT_EQ(kArrow, frame.GetBorderArrow());
  EXPECT_EQ(kColor, frame.GetBorderBackgroundColor());

  const gfx::Insets content_margins = frame.content_margins();
  const gfx::Insets insets = frame.GetBorderInsets();
  const gfx::Rect client_view_bounds = frame.GetBoundsForClientView();
  EXPECT_EQ(insets.left() + content_margins.left(), client_view_bounds.x());
  EXPECT_EQ(insets.top() + content_margins.top(), client_view_bounds.y());
}

TEST_F(BubbleFrameViewTest, GetBoundsForClientViewWithClose) {
  TestBubbleFrameView frame(this);
  frame.widget_delegate()->SetShouldShowCloseButton(true);
  frame.ResetWindowControls();
  EXPECT_EQ(kArrow, frame.GetBorderArrow());
  EXPECT_EQ(kColor, frame.GetBorderBackgroundColor());

  const gfx::Insets content_margins = frame.content_margins();
  const gfx::Insets insets = frame.GetBorderInsets();
  const int close_margin =
      frame.GetCloseButtonForTest()->height() +
      LayoutProvider::Get()->GetDistanceMetric(DISTANCE_CLOSE_BUTTON_MARGIN);
  const gfx::Rect client_view_bounds = frame.GetBoundsForClientView();
  EXPECT_EQ(insets.left() + content_margins.left(), client_view_bounds.x());
  EXPECT_EQ(insets.top() + content_margins.top() + close_margin,
            client_view_bounds.y());
}

TEST_F(BubbleFrameViewTest, RemoveFootnoteView) {
  TestBubbleFrameView frame(this);
  EXPECT_EQ(nullptr, frame.footnote_container_);
  auto footnote = std::make_unique<StaticSizedView>(gfx::Size(200, 200));
  View* footnote_dummy_view = footnote.get();
  frame.SetFootnoteView(std::move(footnote));
  EXPECT_EQ(footnote_dummy_view->parent(), frame.footnote_container_);
  frame.SetFootnoteView(nullptr);
  EXPECT_EQ(nullptr, frame.footnote_container_);
}

TEST_F(BubbleFrameViewTest,
       FootnoteContainerViewShouldMatchVisibilityOfFirstChild) {
  TestBubbleFrameView frame(this);
  std::unique_ptr<View> footnote =
      std::make_unique<StaticSizedView>(gfx::Size(200, 200));
  footnote->SetVisible(false);
  View* footnote_dummy_view = footnote.get();
  frame.SetFootnoteView(std::move(footnote));
  View* footnote_container_view = footnote_dummy_view->parent();
  EXPECT_FALSE(footnote_container_view->GetVisible());
  footnote_dummy_view->SetVisible(true);
  EXPECT_TRUE(footnote_container_view->GetVisible());
  footnote_dummy_view->SetVisible(false);
  EXPECT_FALSE(footnote_container_view->GetVisible());
}

// Tests that the arrow is mirrored as needed to better fit the screen.
TEST_F(BubbleFrameViewTest, GetUpdatedWindowBounds) {
  TestBubbleFrameView frame(this);
  gfx::Rect window_bounds;

  frame.SetBubbleBorder(
      std::make_unique<BubbleBorder>(kArrow, BubbleBorder::NO_SHADOW, kColor));

  // Test that the info bubble displays normally when it fits.
  frame.SetArrow(BubbleBorder::TOP_LEFT);
  window_bounds = frame.GetUpdatedWindowBounds(
      gfx::Rect(100, 100, 0, 0),      // |anchor_rect|
      BubbleBorder::Arrow::TOP_LEFT,  // |delegate_arrow|
      gfx::Size(500, 500),            // |client_size|
      true);                          // |adjust_to_fit_available_bounds|
  EXPECT_EQ(BubbleBorder::TOP_LEFT, frame.GetBorderArrow());
  EXPECT_EQ(window_bounds.x(), 100);
  EXPECT_EQ(window_bounds.y(), 100);

  // Test bubble not fitting on left.
  frame.SetArrow(BubbleBorder::TOP_RIGHT);
  window_bounds = frame.GetUpdatedWindowBounds(
      gfx::Rect(100, 100, 0, 0),       // |anchor_rect|
      BubbleBorder::Arrow::TOP_RIGHT,  // |delegate_arrow|
      gfx::Size(500, 500),             // |client_size|
      true);                           // |adjust_to_fit_available_bounds|
  EXPECT_EQ(BubbleBorder::TOP_LEFT, frame.GetBorderArrow());
  EXPECT_EQ(window_bounds.x(), 100);
  EXPECT_EQ(window_bounds.y(), 100);

  // Test bubble not fitting on left or top.
  frame.SetArrow(BubbleBorder::BOTTOM_RIGHT);
  window_bounds = frame.GetUpdatedWindowBounds(
      gfx::Rect(100, 100, 0, 0),          // |anchor_rect|
      BubbleBorder::Arrow::BOTTOM_RIGHT,  // |delegate_arrow|
      gfx::Size(500, 500),                // |client_size|
      true);                              // |adjust_to_fit_available_bounds|
  EXPECT_EQ(BubbleBorder::TOP_LEFT, frame.GetBorderArrow());
  EXPECT_EQ(window_bounds.x(), 100);
  EXPECT_EQ(window_bounds.y(), 100);

  // Test bubble not fitting on top.
  frame.SetArrow(BubbleBorder::BOTTOM_LEFT);
  window_bounds = frame.GetUpdatedWindowBounds(
      gfx::Rect(100, 100, 0, 0),         // |anchor_rect|
      BubbleBorder::Arrow::BOTTOM_LEFT,  // |delegate_arrow|
      gfx::Size(500, 500),               // |client_size|
      true);                             // |adjust_to_fit_available_bounds|
  EXPECT_EQ(BubbleBorder::TOP_LEFT, frame.GetBorderArrow());
  EXPECT_EQ(window_bounds.x(), 100);
  EXPECT_EQ(window_bounds.y(), 100);

  // Test bubble not fitting on top and right.
  frame.SetArrow(BubbleBorder::BOTTOM_LEFT);
  window_bounds = frame.GetUpdatedWindowBounds(
      gfx::Rect(900, 100, 0, 0),         // |anchor_rect|
      BubbleBorder::Arrow::BOTTOM_LEFT,  // |delegate_arrow|
      gfx::Size(500, 500),               // |client_size|
      true);                             // |adjust_to_fit_available_bounds|
  EXPECT_EQ(BubbleBorder::TOP_RIGHT, frame.GetBorderArrow());
  EXPECT_EQ(window_bounds.right(), 900);
  EXPECT_EQ(window_bounds.y(), 100);

  // Test bubble not fitting on right.
  frame.SetArrow(BubbleBorder::TOP_LEFT);
  window_bounds = frame.GetUpdatedWindowBounds(
      gfx::Rect(900, 100, 0, 0),      // |anchor_rect|
      BubbleBorder::Arrow::TOP_LEFT,  // |delegate_arrow|
      gfx::Size(500, 500),            // |client_size|
      true);                          // |adjust_to_fit_available_bounds|
  EXPECT_EQ(BubbleBorder::TOP_RIGHT, frame.GetBorderArrow());
  EXPECT_EQ(window_bounds.right(), 900);
  EXPECT_EQ(window_bounds.y(), 100);

  // Test bubble not fitting on bottom and right.
  frame.SetArrow(BubbleBorder::TOP_LEFT);
  window_bounds = frame.GetUpdatedWindowBounds(
      gfx::Rect(900, 900, 0, 0),      // |anchor_rect|
      BubbleBorder::Arrow::TOP_LEFT,  // |delegate_arrow|
      gfx::Size(500, 500),            // |client_size|
      true);                          // |adjust_to_fit_available_bounds|
  EXPECT_EQ(BubbleBorder::BOTTOM_RIGHT, frame.GetBorderArrow());
  EXPECT_EQ(window_bounds.right(), 900);
  EXPECT_EQ(window_bounds.bottom(), 900);

  // Test bubble not fitting at the bottom.
  frame.SetArrow(BubbleBorder::TOP_LEFT);
  window_bounds = frame.GetUpdatedWindowBounds(
      gfx::Rect(100, 900, 0, 0),      // |anchor_rect|
      BubbleBorder::Arrow::TOP_LEFT,  // |delegate_arrow|
      gfx::Size(500, 500),            // |client_size|
      true);                          // |adjust_to_fit_available_bounds|
  EXPECT_EQ(BubbleBorder::BOTTOM_LEFT, frame.GetBorderArrow());
  // The window should be right aligned with the anchor_rect.
  EXPECT_EQ(window_bounds.x(), 100);
  EXPECT_EQ(window_bounds.bottom(), 900);

  // Test bubble not fitting at the bottom and left.
  frame.SetArrow(BubbleBorder::TOP_RIGHT);
  window_bounds = frame.GetUpdatedWindowBounds(
      gfx::Rect(100, 900, 0, 0),       // |anchor_rect|
      BubbleBorder::Arrow::TOP_RIGHT,  // |delegate_arrow|
      gfx::Size(500, 500),             // |client_size|
      true);                           // |adjust_to_fit_available_bounds|
  EXPECT_EQ(BubbleBorder::BOTTOM_LEFT, frame.GetBorderArrow());
  // The window should be right aligned with the anchor_rect.
  EXPECT_EQ(window_bounds.x(), 100);
  EXPECT_EQ(window_bounds.bottom(), 900);
}

// Tests that the arrow is not moved when the info-bubble does not fit the
// screen but moving it would make matter worse.
TEST_F(BubbleFrameViewTest, GetUpdatedWindowBoundsMirroringFails) {
  TestBubbleFrameView frame(this);
  frame.SetArrow(BubbleBorder::TOP_LEFT);
  frame.GetUpdatedWindowBounds(
      gfx::Rect(400, 100, 50, 50),    // |anchor_rect|
      BubbleBorder::Arrow::TOP_LEFT,  // |delegate_arrow|
      gfx::Size(500, 700),            // |client_size|
      true);                          // |adjust_to_fit_available_bounds|
  EXPECT_EQ(BubbleBorder::TOP_LEFT, frame.GetBorderArrow());
}

TEST_F(BubbleFrameViewTest, TestMirroringForCenteredArrow) {
  TestBubbleFrameView frame(this);

  // Test bubble not fitting above the anchor.
  frame.SetArrow(BubbleBorder::BOTTOM_CENTER);
  frame.GetUpdatedWindowBounds(
      gfx::Rect(100, 100, 50, 50),         // |anchor_rect|
      BubbleBorder::Arrow::BOTTOM_CENTER,  // |delegate_arrow|
      gfx::Size(500, 700),                 // |client_size|
      true);                               // |adjust_to_fit_available_bounds|
  EXPECT_EQ(BubbleBorder::TOP_CENTER, frame.GetBorderArrow());

  // Test bubble not fitting below the anchor.
  frame.SetArrow(BubbleBorder::TOP_CENTER);
  frame.GetUpdatedWindowBounds(
      gfx::Rect(300, 800, 50, 50),      // |anchor_rect|
      BubbleBorder::Arrow::TOP_CENTER,  // |delegate_arrow|
      gfx::Size(500, 200),              // |client_size|
      true);                            // |adjust_to_fit_available_bounds|
  EXPECT_EQ(BubbleBorder::BOTTOM_CENTER, frame.GetBorderArrow());

  // Test bubble not fitting to the right of the anchor.
  frame.SetArrow(BubbleBorder::LEFT_CENTER);
  frame.GetUpdatedWindowBounds(
      gfx::Rect(800, 300, 50, 50),       // |anchor_rect|
      BubbleBorder::Arrow::LEFT_CENTER,  // |delegate_arrow|
      gfx::Size(200, 500),               // |client_size|
      true);                             // |adjust_to_fit_available_bounds|
  EXPECT_EQ(BubbleBorder::RIGHT_CENTER, frame.GetBorderArrow());

  // Test bubble not fitting to the left of the anchor.
  frame.SetArrow(BubbleBorder::RIGHT_CENTER);
  frame.GetUpdatedWindowBounds(
      gfx::Rect(100, 300, 50, 50),        // |anchor_rect|
      BubbleBorder::Arrow::RIGHT_CENTER,  // |delegate_arrow|
      gfx::Size(500, 500),                // |client_size|
      true);                              // |adjust_to_fit_available_bounds|
  EXPECT_EQ(BubbleBorder::LEFT_CENTER, frame.GetBorderArrow());
}

// Test that the arrow will not be mirrored when
// |adjust_to_fit_available_bounds| is false.
TEST_F(BubbleFrameViewTest, GetUpdatedWindowBoundsDontTryMirror) {
  TestBubbleFrameView frame(this);
  frame.SetBubbleBorder(std::make_unique<BubbleBorder>(
      BubbleBorder::TOP_RIGHT, BubbleBorder::NO_SHADOW, kColor));
  gfx::Rect window_bounds = frame.GetUpdatedWindowBounds(
      gfx::Rect(100, 900, 0, 0),       // |anchor_rect|
      BubbleBorder::Arrow::TOP_RIGHT,  // |delegate_arrow|
      gfx::Size(500, 500),             // |client_size|
      false);                          // |adjust_to_fit_available_bounds|
  EXPECT_EQ(BubbleBorder::TOP_RIGHT, frame.GetBorderArrow());
  // The coordinates should be pointing to anchor_rect from TOP_RIGHT.
  EXPECT_EQ(window_bounds.right(), 100);
  EXPECT_EQ(window_bounds.y(), 900);
}

// Test that the center arrow is moved as needed to fit the screen.
TEST_F(BubbleFrameViewTest, GetUpdatedWindowBoundsCenterArrows) {
  TestBubbleFrameView frame(this);
  gfx::Rect window_bounds;

  frame.SetBubbleBorder(
      std::make_unique<BubbleBorder>(kArrow, BubbleBorder::NO_SHADOW, kColor));

  // Some of these tests may go away once --secondary-ui-md becomes the
  // default. Under Material Design mode, the BubbleBorder doesn't support all
  // "arrow" positions. If this changes, then the tests should be updated or
  // added for MD mode.

  // Test that the bubble displays normally when it fits.
  frame.SetArrow(BubbleBorder::BOTTOM_CENTER);
  window_bounds = frame.GetUpdatedWindowBounds(
      gfx::Rect(500, 900, 50, 50),         // |anchor_rect|
      BubbleBorder::Arrow::BOTTOM_CENTER,  // |delegate_arrow|
      gfx::Size(500, 500),                 // |client_size|
      true);                               // |adjust_to_fit_available_bounds|
  EXPECT_EQ(BubbleBorder::BOTTOM_CENTER, frame.GetBorderArrow());
  EXPECT_EQ(window_bounds.x() + window_bounds.width() / 2, 525);

  frame.SetArrow(BubbleBorder::LEFT_CENTER);
  window_bounds = frame.GetUpdatedWindowBounds(
      gfx::Rect(100, 400, 50, 50),       // |anchor_rect|
      BubbleBorder::Arrow::LEFT_CENTER,  // |delegate_arrow|
      gfx::Size(500, 500),               // |client_size|
      true);                             // |adjust_to_fit_available_bounds|
  EXPECT_EQ(BubbleBorder::LEFT_CENTER, frame.GetBorderArrow());
  EXPECT_EQ(window_bounds.y() + window_bounds.height() / 2, 425);

  frame.SetArrow(BubbleBorder::RIGHT_CENTER);
  window_bounds = frame.GetUpdatedWindowBounds(
      gfx::Rect(900, 400, 50, 50),        // |anchor_rect|
      BubbleBorder::Arrow::RIGHT_CENTER,  // |delegate_arrow|
      gfx::Size(500, 500),                // |client_size|
      true);                              // |adjust_to_fit_available_bounds|
  EXPECT_EQ(BubbleBorder::RIGHT_CENTER, frame.GetBorderArrow());
  EXPECT_EQ(window_bounds.y() + window_bounds.height() / 2, 425);

  // Test bubble not fitting left screen edge.
  frame.SetArrow(BubbleBorder::BOTTOM_CENTER);
  window_bounds = frame.GetUpdatedWindowBounds(
      gfx::Rect(100, 900, 50, 50),         // |anchor_rect|
      BubbleBorder::Arrow::BOTTOM_CENTER,  // |delegate_arrow|
      gfx::Size(500, 500),                 // |client_size|
      true);                               // |adjust_to_fit_available_bounds|
  EXPECT_EQ(BubbleBorder::BOTTOM_CENTER, frame.GetBorderArrow());
  EXPECT_EQ(window_bounds.x(), 0);

  // Test bubble not fitting right screen edge.
  frame.SetArrow(BubbleBorder::BOTTOM_CENTER);
  window_bounds = frame.GetUpdatedWindowBounds(
      gfx::Rect(900, 900, 50, 50),         // |anchor_rect|
      BubbleBorder::Arrow::BOTTOM_CENTER,  // |delegate_arrow|
      gfx::Size(500, 500),                 // |client_size|
      true);                               // |adjust_to_fit_available_bounds|
  EXPECT_EQ(BubbleBorder::BOTTOM_CENTER, frame.GetBorderArrow());
  EXPECT_EQ(window_bounds.right(), 1000);
}

// Tests that the arrow is mirrored as needed to better fit the anchor window's
// bounds.
TEST_F(BubbleFrameViewTest, GetUpdatedWindowBoundsForBubbleWithAnchorWindow) {
  TestBubbleFrameView frame(this);
  frame.SetAvailableAnchorWindowBounds(gfx::Rect(100, 100, 500, 500));
  gfx::Rect window_bounds;

  frame.SetBubbleBorder(
      std::make_unique<BubbleBorder>(kArrow, BubbleBorder::NO_SHADOW, kColor));

  // Test that the bubble displays normally when it fits.
  frame.SetArrow(BubbleBorder::TOP_LEFT);
  window_bounds = frame.GetUpdatedWindowBounds(
      gfx::Rect(200, 200, 0, 0),      // |anchor_rect|
      BubbleBorder::Arrow::TOP_LEFT,  // |delegate_arrow|
      gfx::Size(250, 250),            // |client_size|
      true);                          // |adjust_to_fit_available_bounds|
  EXPECT_EQ(BubbleBorder::TOP_LEFT, frame.GetBorderArrow());
  EXPECT_EQ(window_bounds.x(), 200);
  EXPECT_EQ(window_bounds.y(), 200);

  // Test bubble not fitting on left for anchor window displays left aligned
  // with the left side of the anchor rect.
  frame.SetArrow(BubbleBorder::TOP_RIGHT);
  window_bounds = frame.GetUpdatedWindowBounds(
      gfx::Rect(200, 200, 0, 0),       // |anchor_rect|
      BubbleBorder::Arrow::TOP_RIGHT,  // |delegate_arrow|
      gfx::Size(250, 250),             // |client_size|
      true);                           // |adjust_to_fit_available_bounds|
  EXPECT_EQ(BubbleBorder::TOP_LEFT, frame.GetBorderArrow());
  EXPECT_EQ(window_bounds.x(), 200);
  EXPECT_EQ(window_bounds.y(), 200);

  // Test bubble not fitting on left or top displays left and top aligned
  // with the left and bottom sides of the anchor rect.
  frame.SetArrow(BubbleBorder::BOTTOM_RIGHT);
  window_bounds = frame.GetUpdatedWindowBounds(
      gfx::Rect(200, 200, 0, 0),          // |anchor_rect|
      BubbleBorder::Arrow::BOTTOM_RIGHT,  // |delegate_arrow|
      gfx::Size(250, 250),                // |client_size|
      true);                              // |adjust_to_fit_available_bounds|
  EXPECT_EQ(BubbleBorder::TOP_LEFT, frame.GetBorderArrow());
  EXPECT_EQ(window_bounds.x(), 200);
  EXPECT_EQ(window_bounds.y(), 200);

  // Test bubble not fitting on top displays top aligned with the bottom side of
  // the anchor rect.
  frame.SetArrow(BubbleBorder::BOTTOM_LEFT);
  window_bounds = frame.GetUpdatedWindowBounds(
      gfx::Rect(200, 200, 0, 0),         // |anchor_rect|
      BubbleBorder::Arrow::BOTTOM_LEFT,  // |delegate_arrow|
      gfx::Size(250, 250),               // |client_size|
      true);                             // |adjust_to_fit_available_bounds|
  EXPECT_EQ(BubbleBorder::TOP_LEFT, frame.GetBorderArrow());
  EXPECT_EQ(window_bounds.x(), 200);
  EXPECT_EQ(window_bounds.y(), 200);

  // Test bubble not fitting on top and right displays right and top aligned
  // with the right and bottom sides of the anchor rect.
  frame.SetArrow(BubbleBorder::BOTTOM_LEFT);
  window_bounds = frame.GetUpdatedWindowBounds(
      gfx::Rect(500, 200, 0, 0),         // |anchor_rect|
      BubbleBorder::Arrow::BOTTOM_LEFT,  // |delegate_arrow|
      gfx::Size(250, 250),               // |client_size|
      true);                             // |adjust_to_fit_available_bounds|
  EXPECT_EQ(BubbleBorder::TOP_RIGHT, frame.GetBorderArrow());
  EXPECT_EQ(window_bounds.right(), 500);
  EXPECT_EQ(window_bounds.y(), 200);

  // Test bubble not fitting on right display in line with the right edge of
  // the anchor rect.
  frame.SetArrow(BubbleBorder::TOP_LEFT);
  window_bounds = frame.GetUpdatedWindowBounds(
      gfx::Rect(500, 200, 0, 0),      // |anchor_rect|
      BubbleBorder::Arrow::TOP_LEFT,  // |delegate_arrow|
      gfx::Size(250, 250),            // |client_size|
      true);                          // |adjust_to_fit_available_bounds|
  EXPECT_EQ(BubbleBorder::TOP_RIGHT, frame.GetBorderArrow());
  EXPECT_EQ(window_bounds.right(), 500);
  EXPECT_EQ(window_bounds.y(), 200);

  // Test bubble not fitting on bottom and right displays in line with the right
  // edge of the anchor rect and the bottom in line with the top of the anchor
  // rect.
  frame.SetArrow(BubbleBorder::TOP_LEFT);
  window_bounds = frame.GetUpdatedWindowBounds(
      gfx::Rect(500, 500, 0, 0),      // |anchor_rect|
      BubbleBorder::Arrow::TOP_LEFT,  // |delegate_arrow|
      gfx::Size(250, 250),            // |client_size|
      true);                          // |adjust_to_fit_available_bounds|
  EXPECT_EQ(BubbleBorder::BOTTOM_RIGHT, frame.GetBorderArrow());
  EXPECT_EQ(window_bounds.right(), 500);
  EXPECT_EQ(window_bounds.bottom(), 500);

  // Test bubble not fitting at the bottom displays line with the top of the
  // anchor rect.
  frame.SetArrow(BubbleBorder::TOP_LEFT);
  window_bounds = frame.GetUpdatedWindowBounds(
      gfx::Rect(200, 500, 0, 0),      // |anchor_rect|
      BubbleBorder::Arrow::TOP_LEFT,  // |delegate_arrow|
      gfx::Size(250, 250),            // |client_size|
      true);                          // |adjust_to_fit_available_bounds|
  EXPECT_EQ(BubbleBorder::BOTTOM_LEFT, frame.GetBorderArrow());
  EXPECT_EQ(window_bounds.x(), 200);
  EXPECT_EQ(window_bounds.bottom(), 500);

  // Test bubble not fitting at the bottom and left displays right aligned with
  // the anchor rect and the bottom in line with the top of the anchor rect.
  frame.SetArrow(BubbleBorder::TOP_RIGHT);
  window_bounds = frame.GetUpdatedWindowBounds(
      gfx::Rect(200, 500, 0, 0),       // |anchor_rect|
      BubbleBorder::Arrow::TOP_RIGHT,  // |delegate_arrow|
      gfx::Size(250, 250),             // |client_size|
      true);                           // |adjust_to_fit_available_bounds|
  EXPECT_EQ(BubbleBorder::BOTTOM_LEFT, frame.GetBorderArrow());
  EXPECT_EQ(window_bounds.x(), 200);
  EXPECT_EQ(window_bounds.bottom(), 500);
}

// Tests that the arrow is mirrored as needed to better fit the screen.
TEST_F(BubbleFrameViewTest,
       GetUpdatedWindowBoundsForBubbleWithAnchorWindowExitingScreen) {
  TestBubbleFrameView frame(this);
  gfx::Rect window_bounds;

  frame.SetBubbleBorder(
      std::make_unique<BubbleBorder>(kArrow, BubbleBorder::NO_SHADOW, kColor));

  // Test bubble fitting anchor window and not fitting screen on right.
  //     ________________________
  //    |screen _________________|__________
  //    |      |anchor window ___|___       |
  //    |      |             |bubble |      |
  //    |      |             |_______|      |
  //    |      |_________________|__________|
  //    |________________________|
  frame.SetAvailableAnchorWindowBounds(gfx::Rect(700, 200, 400, 400));
  frame.SetArrow(BubbleBorder::TOP_LEFT);
  window_bounds = frame.GetUpdatedWindowBounds(
      gfx::Rect(800, 300, 0, 0),      // |anchor_rect|
      BubbleBorder::Arrow::TOP_LEFT,  // |delegate_arrow|
      gfx::Size(250, 250),            // |client_size|
      true);                          // |adjust_to_fit_available_bounds|
  EXPECT_EQ(BubbleBorder::TOP_RIGHT, frame.GetBorderArrow());
  // The window should be right aligned with the anchor_rect.
  EXPECT_EQ(window_bounds.right(), 800);
  EXPECT_EQ(window_bounds.y(), 300);

  // Test bubble fitting anchor window and not fitting screen on right and
  // bottom.
  //     ________________________
  //    |screen                  |
  //    |       _________________|__________
  //    |      |anchor window ___|___       |
  //    |______|_____________|bubble |      |
  //           |             |_______|      |
  //           |____________________________|
  frame.SetAvailableAnchorWindowBounds(gfx::Rect(700, 700, 400, 400));
  frame.SetArrow(BubbleBorder::TOP_LEFT);
  window_bounds = frame.GetUpdatedWindowBounds(
      gfx::Rect(800, 800, 0, 0),      // |anchor_rect|
      BubbleBorder::Arrow::TOP_LEFT,  // |delegate_arrow|
      gfx::Size(250, 250),            // |client_size|
      true);                          // |adjust_to_fit_available_bounds|
  EXPECT_EQ(BubbleBorder::BOTTOM_RIGHT, frame.GetBorderArrow());
  // The window should be right aligned with the anchor_rect.
  EXPECT_EQ(window_bounds.right(), 800);
  EXPECT_EQ(window_bounds.bottom(), 800);

  // Test bubble not fitting anchor window on bottom and not fitting screen on
  // right.
  //     ________________________
  //    |screen _________________|__________
  //    |      |anchor window    |          |
  //    |      |              ___|___       |
  //    |      |_____________|bubble |______|
  //    |                    |_______|
  //    |________________________|
  frame.SetAvailableAnchorWindowBounds(gfx::Rect(700, 200, 400, 400));
  frame.SetArrow(BubbleBorder::TOP_LEFT);
  window_bounds = frame.GetUpdatedWindowBounds(
      gfx::Rect(800, 500, 0, 0),      // |anchor_rect|
      BubbleBorder::Arrow::TOP_LEFT,  // |delegate_arrow|
      gfx::Size(250, 250),            // |client_size|
      true);                          // |adjust_to_fit_available_bounds|
  EXPECT_EQ(BubbleBorder::BOTTOM_RIGHT, frame.GetBorderArrow());
  // The window should be right aligned with the anchor_rect.
  EXPECT_EQ(window_bounds.right(), 800);
  EXPECT_EQ(window_bounds.bottom(), 500);
}

// Tests that the arrow is mirrored as needed to better fit the anchor window's
// bounds.
TEST_F(BubbleFrameViewTest, MirroringNotStickyForGetUpdatedWindowBounds) {
  TestBubbleFrameView frame(this);
  gfx::Rect window_bounds;

  frame.SetBubbleBorder(
      std::make_unique<BubbleBorder>(kArrow, BubbleBorder::NO_SHADOW, kColor));

  // Test bubble fitting anchor window and not fitting screen on right.
  frame.SetAvailableAnchorWindowBounds(gfx::Rect(700, 200, 400, 400));
  frame.SetArrow(BubbleBorder::TOP_LEFT);
  window_bounds = frame.GetUpdatedWindowBounds(
      gfx::Rect(800, 300, 0, 0),      // |anchor_rect|
      BubbleBorder::Arrow::TOP_LEFT,  // |delegate_arrow|
      gfx::Size(250, 250),            // |client_size|
      true);                          // |adjust_to_fit_available_bounds|
  EXPECT_EQ(BubbleBorder::TOP_RIGHT, frame.GetBorderArrow());
  // The window should be right aligned with the anchor_rect.
  EXPECT_EQ(window_bounds.right(), 800);
  EXPECT_EQ(window_bounds.y(), 300);

  // Test that the bubble mirrors again if it can fit on screen with its
  // original anchor.
  window_bounds = frame.GetUpdatedWindowBounds(
      gfx::Rect(700, 300, 0, 0),      // |anchor_rect|
      BubbleBorder::Arrow::TOP_LEFT,  // |delegate_arrow|
      gfx::Size(250, 250),            // |client_size|
      true);                          // |adjust_to_fit_available_bounds|
  EXPECT_EQ(BubbleBorder::TOP_LEFT, frame.GetBorderArrow());
  // The window should be right aligned with the anchor_rect.
  EXPECT_EQ(window_bounds.x(), 700);
  EXPECT_EQ(window_bounds.y(), 300);
}

// Tests that the arrow is offset as needed to better fit the window.
TEST_F(BubbleFrameViewTest, GetUpdatedWindowBoundsForBubbleSetToOffset) {
  TestBubbleFrameView frame(this);
  frame.SetAvailableAnchorWindowBounds(gfx::Rect(100, 100, 500, 500));
  frame.set_preferred_arrow_adjustment(
      BubbleFrameView::PreferredArrowAdjustment::kOffset);
  gfx::Rect window_bounds;

  frame.SetBubbleBorder(
      std::make_unique<BubbleBorder>(kArrow, BubbleBorder::NO_SHADOW, kColor));

  // Test that the bubble displays normally when it fits.
  frame.SetArrow(BubbleBorder::TOP_LEFT);
  window_bounds = frame.GetUpdatedWindowBounds(
      gfx::Rect(200, 200, 0, 0),      // |anchor_rect|
      BubbleBorder::Arrow::TOP_LEFT,  // |delegate_arrow|
      gfx::Size(250, 250),            // |client_size|
      true);                          // |adjust_to_fit_available_bounds|
  EXPECT_EQ(BubbleBorder::TOP_LEFT, frame.GetBorderArrow());
  EXPECT_EQ(window_bounds.x(), 200);

  // Test bubble not fitting left window edge displayed against left window
  // edge.
  frame.SetArrow(BubbleBorder::TOP_RIGHT);
  window_bounds = frame.GetUpdatedWindowBounds(
      gfx::Rect(200, 200, 0, 0),       // |anchor_rect|
      BubbleBorder::Arrow::TOP_RIGHT,  // |delegate_arrow|
      gfx::Size(250, 250),             // |client_size|
      true);                           // |adjust_to_fit_available_bounds|
  EXPECT_EQ(BubbleBorder::TOP_RIGHT, frame.GetBorderArrow());
  EXPECT_EQ(window_bounds.x(), 100);

  // Test bubble not fitting right window edge displays against the right edge
  // of the anchor window.
  frame.SetArrow(BubbleBorder::TOP_LEFT);
  window_bounds = frame.GetUpdatedWindowBounds(
      gfx::Rect(500, 200, 0, 0),      // |anchor_rect|
      BubbleBorder::Arrow::TOP_LEFT,  // |delegate_arrow|
      gfx::Size(250, 250),            // |client_size|
      true);                          // |adjust_to_fit_available_bounds|
  EXPECT_EQ(BubbleBorder::TOP_LEFT, frame.GetBorderArrow());
  EXPECT_EQ(window_bounds.right(), 600);

  // Test bubble fitting anchor window and not fitting screen on right displays
  // against the right edge of the screen.
  frame.SetAvailableAnchorWindowBounds(gfx::Rect(800, 300, 500, 500));
  frame.SetArrow(BubbleBorder::TOP_LEFT);
  window_bounds = frame.GetUpdatedWindowBounds(
      gfx::Rect(900, 500, 0, 0),      // |anchor_rect|
      BubbleBorder::Arrow::TOP_LEFT,  // |delegate_arrow|
      gfx::Size(250, 250),            // |client_size|
      true);                          // |adjust_to_fit_available_bounds|
  EXPECT_EQ(BubbleBorder::TOP_LEFT, frame.GetBorderArrow());
  EXPECT_EQ(window_bounds.right(), 1000);
}

// Tests that the arrow is offset as needed to better fit the window for
// windows larger than the available bounds.
TEST_F(BubbleFrameViewTest,
       GetUpdatedWindowBoundsForBubbleSetToOffsetLargerThanAvailableBounds) {
  TestBubbleFrameView frame(this);
  frame.SetAvailableAnchorWindowBounds(gfx::Rect(200, 200, 500, 500));
  frame.set_preferred_arrow_adjustment(
      BubbleFrameView::PreferredArrowAdjustment::kOffset);
  gfx::Rect window_bounds;

  frame.SetBubbleBorder(
      std::make_unique<BubbleBorder>(kArrow, BubbleBorder::NO_SHADOW, kColor));

  // Test that the bubble exiting right side of anchor window displays against
  // left edge of anchor window bounds if larger than anchor window.
  frame.SetArrow(BubbleBorder::TOP_LEFT);
  window_bounds = frame.GetUpdatedWindowBounds(
      gfx::Rect(300, 300, 0, 0),      // |anchor_rect|
      BubbleBorder::Arrow::TOP_LEFT,  // |delegate_arrow|
      gfx::Size(600, 250),            // |client_size|
      true);                          // |adjust_to_fit_available_bounds|
  EXPECT_EQ(BubbleBorder::TOP_LEFT, frame.GetBorderArrow());
  EXPECT_EQ(window_bounds.x(), 200);

  // Test that the bubble exiting left side of anchor window displays against
  // right edge of anchor window bounds if larger than anchor window.
  frame.SetArrow(BubbleBorder::TOP_RIGHT);
  window_bounds = frame.GetUpdatedWindowBounds(
      gfx::Rect(300, 300, 0, 0),       // |anchor_rect|
      BubbleBorder::Arrow::TOP_RIGHT,  // |delegate_arrow|
      gfx::Size(600, 250),             // |client_size|
      true);                           // |adjust_to_fit_available_bounds|
  EXPECT_EQ(BubbleBorder::TOP_RIGHT, frame.GetBorderArrow());
  // Check that the right edge of the bubble equals the right edge of the
  // anchor window.
  EXPECT_EQ(window_bounds.right(), 700);

  // Test that the bubble exiting bottom side of anchor window displays against
  // top edge of anchor window bounds if larger than anchor window.
  frame.SetArrow(BubbleBorder::LEFT_TOP);
  window_bounds = frame.GetUpdatedWindowBounds(
      gfx::Rect(400, 400, 0, 0),      // |anchor_rect|
      BubbleBorder::Arrow::LEFT_TOP,  // |delegate_arrow|
      gfx::Size(250, 600),            // |client_size|
      true);                          // |adjust_to_fit_available_bounds|
  EXPECT_EQ(BubbleBorder::LEFT_TOP, frame.GetBorderArrow());
  EXPECT_EQ(window_bounds.y(), 200);

  // Test that the bubble exiting top side of anchor window displays against
  // bottom edge of anchor window bounds if larger than anchor window.
  frame.SetArrow(BubbleBorder::LEFT_BOTTOM);
  window_bounds = frame.GetUpdatedWindowBounds(
      gfx::Rect(300, 300, 0, 0),         // |anchor_rect|
      BubbleBorder::Arrow::LEFT_BOTTOM,  // |delegate_arrow|
      gfx::Size(250, 600),               // |client_size|
      true);                             // |adjust_to_fit_available_bounds|
  EXPECT_EQ(BubbleBorder::LEFT_BOTTOM, frame.GetBorderArrow());
  EXPECT_EQ(window_bounds.bottom(), 700);
}

TEST_F(BubbleFrameViewTest, GetPreferredSize) {
  // Test border/insets.
  TestBubbleFrameView frame(this);
  gfx::Rect preferred_rect(frame.GetPreferredSize());
  // Expect that a border has been added to the preferred size.
  preferred_rect.Inset(frame.GetBorderInsets());

  gfx::Size expected_size(kPreferredClientWidth + kExpectedAdditionalWidth,
                          kPreferredClientHeight + kExpectedAdditionalHeight);
  EXPECT_EQ(expected_size, preferred_rect.size());
}

TEST_F(BubbleFrameViewTest, GetPreferredSizeWithFootnote) {
  // Test footnote view: adding a footnote should increase the preferred size,
  // but only when the footnote is visible.
  TestBubbleFrameView frame(this);

  constexpr int kFootnoteHeight = 20;
  const gfx::Size no_footnote_size = frame.GetPreferredSize();
  std::unique_ptr<View> footnote =
      std::make_unique<StaticSizedView>(gfx::Size(10, kFootnoteHeight));
  footnote->SetVisible(false);
  View* footnote_dummy_view = footnote.get();
  frame.SetFootnoteView(std::move(footnote));
  EXPECT_EQ(no_footnote_size, frame.GetPreferredSize());  // No change.

  footnote_dummy_view->SetVisible(true);
  gfx::Size with_footnote_size = no_footnote_size;
  constexpr int kFootnoteTopBorderThickness = 1;
  with_footnote_size.Enlarge(0, kFootnoteHeight + kFootnoteTopBorderThickness +
                                    frame.content_margins().height());
  EXPECT_EQ(with_footnote_size, frame.GetPreferredSize());

  footnote_dummy_view->SetVisible(false);
  EXPECT_EQ(no_footnote_size, frame.GetPreferredSize());
}

TEST_F(BubbleFrameViewTest, GetMinimumSize) {
  TestBubbleFrameView frame(this);
  gfx::Rect minimum_rect(frame.GetMinimumSize());
  // Expect that a border has been added to the minimum size.
  minimum_rect.Inset(frame.GetBorderInsets());

  gfx::Size expected_size(kMinimumClientWidth + kExpectedAdditionalWidth,
                          kMinimumClientHeight + kExpectedAdditionalHeight);
  EXPECT_EQ(expected_size, minimum_rect.size());
}

TEST_F(BubbleFrameViewTest, GetMaximumSize) {
  TestBubbleFrameView frame(this);
  gfx::Rect maximum_rect(frame.GetMaximumSize());
#if defined(OS_WIN)
  // On Windows, GetMaximumSize causes problems with DWM, so it should just be 0
  // (unlimited). See http://crbug.com/506206.
  EXPECT_EQ(gfx::Size(), maximum_rect.size());
#else
  maximum_rect.Inset(frame.GetBorderInsets());

  // Should ignore the contents view's maximum size and use the preferred size.
  gfx::Size expected_size(kPreferredClientWidth + kExpectedAdditionalWidth,
                          kPreferredClientHeight + kExpectedAdditionalHeight);
  EXPECT_EQ(expected_size, maximum_rect.size());
#endif
}

namespace {

class TestBubbleDialogDelegateView : public BubbleDialogDelegateView {
 public:
  TestBubbleDialogDelegateView()
      : BubbleDialogDelegateView(nullptr, BubbleBorder::NONE) {
    set_shadow(BubbleBorder::NO_ASSETS);
    SetAnchorRect(gfx::Rect());
  }
  ~TestBubbleDialogDelegateView() override = default;

  void ChangeTitle(const base::string16& title) {
    title_ = title;
    // Note UpdateWindowTitle() always does a layout, which will be invalid if
    // the Widget needs to change size. But also SizeToContents() _only_ does a
    // layout if the size is actually changing.
    GetWidget()->UpdateWindowTitle();
    SizeToContents();
  }

  void set_icon(const gfx::ImageSkia& icon) { icon_ = icon; }

  // BubbleDialogDelegateView:
  using BubbleDialogDelegateView::SetAnchorView;
  using BubbleDialogDelegateView::SizeToContents;
  gfx::ImageSkia GetWindowIcon() override { return icon_; }
  bool ShouldShowWindowIcon() const override { return !icon_.isNull(); }
  base::string16 GetWindowTitle() const override { return title_; }
  bool ShouldShowWindowTitle() const override { return !title_.empty(); }

  void DeleteDelegate() override {
    // This delegate is owned by the test case itself, so it should not delete
    // itself here. But DialogDelegates shouldn't be reused, so check for that.
    destroyed_ = true;
  }
  int GetDialogButtons() const override { return ui::DIALOG_BUTTON_OK; }
  gfx::Size CalculatePreferredSize() const override {
    return gfx::Size(200, 200);
  }
  void Init() override { DCHECK(!destroyed_); }

  BubbleFrameView* GetBubbleFrameView() const {
    return static_cast<BubbleFrameView*>(
        GetWidget()->non_client_view()->frame_view());
  }

 private:
  gfx::ImageSkia icon_;
  base::string16 title_;
  bool destroyed_ = false;

  DISALLOW_COPY_AND_ASSIGN(TestBubbleDialogDelegateView);
};

class TestAnchor {
 public:
  explicit TestAnchor(Widget::InitParams params) {
    params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
    widget_.Init(params);
    widget_.Show();
  }

  Widget& widget() { return widget_; }

 private:
  Widget widget_;

  DISALLOW_COPY_AND_ASSIGN(TestAnchor);
};

// BubbleDialogDelegate with no margins to test width snapping.
class TestWidthSnapDelegate : public TestBubbleDialogDelegateView {
 public:
  TestWidthSnapDelegate(TestAnchor* anchor, bool should_snap)
      : should_snap_(should_snap) {
    SetAnchorView(anchor->widget().GetContentsView());
    set_margins(gfx::Insets());
    BubbleDialogDelegateView::CreateBubble(this);
    GetWidget()->Show();
  }

  ~TestWidthSnapDelegate() override { GetWidget()->CloseNow(); }

  // TestBubbleDialogDelegateView:
  bool ShouldSnapFrameWidth() const override { return should_snap_; }

 private:
  bool should_snap_;

  DISALLOW_COPY_AND_ASSIGN(TestWidthSnapDelegate);
};

}  // namespace

// This test ensures that if the installed LayoutProvider snaps dialog widths,
// BubbleFrameView correctly sizes itself to that width.
TEST_F(BubbleFrameViewTest, WidthSnaps) {
  test::TestLayoutProvider provider;
  TestAnchor anchor(CreateParams(Widget::InitParams::TYPE_WINDOW));

  {
    TestWidthSnapDelegate delegate(&anchor, true);
    EXPECT_EQ(delegate.GetPreferredSize().width(),
              delegate.GetWidget()->GetWindowBoundsInScreen().width());
  }

  constexpr int kTestWidth = 300;
  provider.SetSnappedDialogWidth(kTestWidth);

  {
    TestWidthSnapDelegate delegate(&anchor, true);
    // The Widget's snapped width should exactly match the width returned by the
    // LayoutProvider.
    EXPECT_EQ(kTestWidth,
              delegate.GetWidget()->GetWindowBoundsInScreen().width());
  }

  {
    // If the DialogDelegate asks not to snap, it should not snap.
    TestWidthSnapDelegate delegate(&anchor, false);
    EXPECT_EQ(delegate.GetPreferredSize().width(),
              delegate.GetWidget()->GetWindowBoundsInScreen().width());
  }
}

// Tests edge cases when the frame's title view starts to wrap text. This is to
// ensure that the calculations BubbleFrameView does to determine the Widget
// size for a given client view are consistent with the eventual size that the
// client view takes after Layout().
TEST_F(BubbleFrameViewTest, LayoutEdgeCases) {
  test::TestLayoutProvider provider;
  TestBubbleDialogDelegateView delegate;
  TestAnchor anchor(CreateParams(Widget::InitParams::TYPE_WINDOW));
  delegate.SetAnchorView(anchor.widget().GetContentsView());

  Widget* bubble = BubbleDialogDelegateView::CreateBubble(&delegate);
  bubble->Show();

  // Even though the bubble has default margins, the dialog view should have
  // been given its preferred size.
  EXPECT_FALSE(delegate.margins().IsEmpty());
  EXPECT_EQ(delegate.size(), delegate.GetPreferredSize());

  // Starting with a short title.
  base::string16 title(1, 'i');
  delegate.ChangeTitle(title);
  const int min_bubble_height = bubble->GetWindowBoundsInScreen().height();
  EXPECT_LT(delegate.GetPreferredSize().height(), min_bubble_height);

  // Grow the title incrementally until word wrap is required. There should
  // never be a point where the BubbleFrameView over- or under-estimates the
  // size required for the title. If it did, it would cause SizeToContents() to
  // Widget size requiring the subsequent Layout() to fill the remaining client
  // area with something other than |delegate|'s preferred size.
  while (bubble->GetWindowBoundsInScreen().height() == min_bubble_height) {
    title += ' ';
    title += 'i';
    delegate.ChangeTitle(title);
    EXPECT_EQ(delegate.GetPreferredSize(), delegate.size()) << title;
  }

  // Sanity check that something interesting happened. The bubble should have
  // grown by "a line" for the wrapped title, and the title should have reached
  // a length that would have likely caused word wrap. A typical result would be
  // a +17-20 change in height and title length of 53 characters.
  const int two_line_height = bubble->GetWindowBoundsInScreen().height();
  EXPECT_LT(12, two_line_height - min_bubble_height);
  EXPECT_GT(25, two_line_height - min_bubble_height);
  EXPECT_LT(30u, title.size());
  EXPECT_GT(80u, title.size());

  // Now add dialog snapping.
  provider.SetSnappedDialogWidth(300);
  delegate.SizeToContents();

  // Height should go back to |min_bubble_height| since the window is wider:
  // word wrapping should no longer happen.
  EXPECT_EQ(min_bubble_height, bubble->GetWindowBoundsInScreen().height());
  EXPECT_EQ(300, bubble->GetWindowBoundsInScreen().width());

  // Now we are allowed to diverge from the client view width, but not height.
  EXPECT_EQ(delegate.GetPreferredSize().height(), delegate.height());
  EXPECT_LT(delegate.GetPreferredSize().width(), delegate.width());
  EXPECT_GT(300, delegate.width());  // Greater, since there are margins.

  const gfx::Size snapped_size = delegate.size();
  const size_t old_title_size = title.size();

  // Grow the title again with width snapping until word wrapping occurs.
  while (bubble->GetWindowBoundsInScreen().height() == min_bubble_height) {
    title += ' ';
    title += 'i';
    delegate.ChangeTitle(title);
    EXPECT_EQ(snapped_size, delegate.size()) << title;
  }
  // Change to the height should have been the same as before. Title should
  // have grown about 50%.
  EXPECT_EQ(two_line_height, bubble->GetWindowBoundsInScreen().height());
  EXPECT_LT(15u, title.size() - old_title_size);
  EXPECT_GT(40u, title.size() - old_title_size);

  // When |anchor| goes out of scope it should take |bubble| with it.
}

TEST_F(BubbleFrameViewTest, LayoutWithIcon) {
  TestBubbleDialogDelegateView delegate;
  TestAnchor anchor(CreateParams(Widget::InitParams::TYPE_WINDOW));
  delegate.SetAnchorView(anchor.widget().GetContentsView());
  SkBitmap bitmap;
  bitmap.allocN32Pixels(20, 80);
  bitmap.eraseColor(SK_ColorYELLOW);
  delegate.set_icon(gfx::ImageSkia::CreateFrom1xBitmap(bitmap));

  Widget* widget = BubbleDialogDelegateView::CreateBubble(&delegate);
  widget->Show();

  delegate.ChangeTitle(base::ASCIIToUTF16("test title"));
  BubbleFrameView* frame = delegate.GetBubbleFrameView();
  View* icon = frame->title_icon_;
  View* title = frame->title();

  // There should be equal amounts of space on the left and right of the icon.
  EXPECT_EQ(icon->x() * 2 + icon->width(), title->x());

  // The title should be vertically centered relative to the icon.
  EXPECT_LT(title->height(), icon->height());
  const int title_offset_y = (icon->height() - title->height()) / 2;
  EXPECT_EQ(icon->y() + title_offset_y, title->y());
}

// Test the size of the bubble allows a |gfx::NO_ELIDE| title to fit, even if
// there is no content.
TEST_F(BubbleFrameViewTest, NoElideTitle) {
  test::TestLayoutProvider provider;
  TestBubbleDialogDelegateView delegate;
  TestAnchor anchor(CreateParams(Widget::InitParams::TYPE_WINDOW));
  delegate.SetAnchorView(anchor.widget().GetContentsView());

  // Make sure the client area size doesn't interfere with the final size.
  delegate.SetPreferredSize(gfx::Size());

  Widget* bubble = BubbleDialogDelegateView::CreateBubble(&delegate);
  bubble->Show();

  // Before changing the title, get the base width of the bubble when there's no
  // title or content in it.
  const int empty_bubble_width = bubble->GetClientAreaBoundsInScreen().width();
  base::string16 title = base::ASCIIToUTF16("This is a title string");
  delegate.ChangeTitle(title);
  Label* title_label =
      static_cast<Label*>(delegate.GetBubbleFrameView()->title());

  // Sanity check: Title labels default to multiline and elide tail. Either of
  // which result in the Layout system making the title and resulting dialog
  // very narrow.
  EXPECT_EQ(gfx::ELIDE_TAIL, title_label->GetElideBehavior());
  EXPECT_TRUE(title_label->GetMultiLine());
  EXPECT_GT(empty_bubble_width, title_label->size().width());
  EXPECT_EQ(empty_bubble_width, bubble->GetClientAreaBoundsInScreen().width());

  // Set the title to a non-eliding label.
  title_label->SetElideBehavior(gfx::NO_ELIDE);
  title_label->SetMultiLine(false);

  // Update the bubble size now that some properties of the title have changed.
  delegate.SizeToContents();

  // The title/bubble should now be bigger than in multiline tail-eliding mode.
  EXPECT_LT(empty_bubble_width, title_label->size().width());
  EXPECT_LT(empty_bubble_width, bubble->GetClientAreaBoundsInScreen().width());

  // Make sure the bubble is wide enough to fit the title's full size. Frame
  // sizing is done off the title label's minimum size. But since that label is
  // set to NO_ELIDE, the minimum size should match the preferred size.
  EXPECT_GE(bubble->GetClientAreaBoundsInScreen().width(),
            title_label->GetPreferredSize().width());
  EXPECT_LE(title_label->GetPreferredSize().width(),
            title_label->size().width());
  EXPECT_EQ(title, title_label->GetDisplayTextForTesting());
}

// Ensures that clicks are ignored for short time after view has been shown.
TEST_F(BubbleFrameViewTest, IgnorePossiblyUnintendedClicks) {
  TestBubbleDialogDelegateView delegate;
  TestAnchor anchor(CreateParams(Widget::InitParams::TYPE_WINDOW));
  delegate.SetAnchorView(anchor.widget().GetContentsView());
  Widget* bubble = BubbleDialogDelegateView::CreateBubble(&delegate);
  bubble->Show();

  BubbleFrameView* frame = delegate.GetBubbleFrameView();
  frame->ButtonPressed(
      frame->close_,
      ui::MouseEvent(ui::ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(),
                     ui::EventTimeForNow(), ui::EF_NONE, ui::EF_NONE));
  EXPECT_FALSE(bubble->IsClosed());

  frame->ButtonPressed(
      frame->close_,
      ui::MouseEvent(ui::ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(),
                     ui::EventTimeForNow() + base::TimeDelta::FromMilliseconds(
                                                 GetDoubleClickInterval()),
                     ui::EF_NONE, ui::EF_NONE));
  EXPECT_TRUE(bubble->IsClosed());
}

}  // namespace views
