15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "ui/base/hit_test.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/bubble/bubble_delegate.h"
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/bubble/bubble_frame_view.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/views/test/test_widget_observer.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/test/views_test_base.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/widget/widget.h"
117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "ui/views/widget/widget_observer.h"
127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace views {
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TestBubbleDelegateView : public BubbleDelegateView {
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
193240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  TestBubbleDelegateView(View* anchor_view)
203240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      : BubbleDelegateView(anchor_view, BubbleBorder::TOP_LEFT),
213240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch        view_(new View()) {
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    view_->SetFocusable(true);
233240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    AddChildView(view_);
243240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  }
253240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  virtual ~TestBubbleDelegateView() {}
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  void SetAnchorRectForTest(gfx::Rect rect) {
28f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    SetAnchorRect(rect);
294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  void SetAnchorViewForTest(View* view) {
324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    SetAnchorView(view);
334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
353240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // BubbleDelegateView overrides:
363240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  virtual View* GetInitiallyFocusedView() OVERRIDE { return view_; }
37cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual gfx::Size GetPreferredSize() const OVERRIDE {
38cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return gfx::Size(200, 200);
39cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  View* view_;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
443240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  DISALLOW_COPY_AND_ASSIGN(TestBubbleDelegateView);
453240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch};
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
473240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochclass BubbleDelegateTest : public ViewsTestBase {
483240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch public:
493240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  BubbleDelegateTest() {}
503240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  virtual ~BubbleDelegateTest() {}
513240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
523240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Creates a test widget that owns its native widget.
533240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  Widget* CreateTestWidget() {
543240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    Widget* widget = new Widget();
553240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_WINDOW);
563240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
573240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    widget->Init(params);
583240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    return widget;
593240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  }
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
613240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch private:
623240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  DISALLOW_COPY_AND_ASSIGN(BubbleDelegateTest);
633240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch};
647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(BubbleDelegateTest, CreateDelegate) {
683240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  scoped_ptr<Widget> anchor_widget(CreateTestWidget());
693240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  BubbleDelegateView* bubble_delegate = new BubbleDelegateView(
703240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      anchor_widget->GetContentsView(), BubbleBorder::NONE);
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bubble_delegate->set_color(SK_ColorGREEN);
723240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  Widget* bubble_widget = BubbleDelegateView::CreateBubble(bubble_delegate);
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(bubble_delegate, bubble_widget->widget_delegate());
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(bubble_widget, bubble_delegate->GetWidget());
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  test::TestWidgetObserver bubble_observer(bubble_widget);
763240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  bubble_widget->Show();
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BubbleBorder* border = bubble_delegate->GetBubbleFrameView()->bubble_border();
79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(bubble_delegate->arrow(), border->arrow());
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(bubble_delegate->color(), border->background_color());
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
823240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  EXPECT_FALSE(bubble_observer.widget_closed());
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bubble_widget->CloseNow();
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(bubble_observer.widget_closed());
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(BubbleDelegateTest, CloseAnchorWidget) {
883240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  scoped_ptr<Widget> anchor_widget(CreateTestWidget());
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BubbleDelegateView* bubble_delegate = new BubbleDelegateView(
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      anchor_widget->GetContentsView(), BubbleBorder::NONE);
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Preventing close on deactivate should not prevent closing with the anchor.
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bubble_delegate->set_close_on_deactivate(false);
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* bubble_widget = BubbleDelegateView::CreateBubble(bubble_delegate);
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(bubble_delegate, bubble_widget->widget_delegate());
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(bubble_widget, bubble_delegate->GetWidget());
963240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  EXPECT_EQ(anchor_widget, bubble_delegate->anchor_widget());
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  test::TestWidgetObserver bubble_observer(bubble_widget);
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(bubble_observer.widget_closed());
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bubble_widget->Show();
1013240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  EXPECT_EQ(anchor_widget, bubble_delegate->anchor_widget());
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(bubble_observer.widget_closed());
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(msw): Remove activation hack to prevent bookkeeping errors in:
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //            aura::test::TestActivationClient::OnWindowDestroyed().
1063240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  scoped_ptr<Widget> smoke_and_mirrors_widget(CreateTestWidget());
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(bubble_observer.widget_closed());
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that closing the anchor widget also closes the bubble itself.
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  anchor_widget->CloseNow();
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(bubble_observer.widget_closed());
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// This test checks that the bubble delegate is capable to handle an early
1154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// destruction of the used anchor view. (Animations and delayed closure of the
1164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// bubble will call upon the anchor view to get its location).
1174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_F(BubbleDelegateTest, CloseAnchorViewTest) {
1184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Create an anchor widget and add a view to be used as an anchor view.
1194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  scoped_ptr<Widget> anchor_widget(CreateTestWidget());
1204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  scoped_ptr<View> anchor_view(new View());
1214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  anchor_widget->GetContentsView()->AddChildView(anchor_view.get());
1224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  TestBubbleDelegateView* bubble_delegate = new TestBubbleDelegateView(
1234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      anchor_view.get());
1244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Prevent flakes by avoiding closing on activation changes.
1254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  bubble_delegate->set_close_on_deactivate(false);
1264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  Widget* bubble_widget = BubbleDelegateView::CreateBubble(bubble_delegate);
1274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Check that the anchor view is correct and set up an anchor view rect.
1294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Make sure that this rect will get ignored (as long as the anchor view is
1304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // attached).
1314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(anchor_view, bubble_delegate->GetAnchorView());
1324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const gfx::Rect set_anchor_rect = gfx::Rect(10, 10, 100, 100);
1334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  bubble_delegate->SetAnchorRectForTest(set_anchor_rect);
1344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const gfx::Rect view_rect = bubble_delegate->GetAnchorRect();
1354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_NE(view_rect.ToString(), set_anchor_rect.ToString());
1364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Create the bubble.
1384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  bubble_widget->Show();
1394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(anchor_widget, bubble_delegate->anchor_widget());
1404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Remove now the anchor view and make sure that the original found rect
1424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // is still kept, so that the bubble does not jump when the view gets deleted.
1434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  anchor_widget->GetContentsView()->RemoveChildView(anchor_view.get());
1444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  anchor_view.reset();
1454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(NULL, bubble_delegate->GetAnchorView());
1464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(view_rect.ToString(), bubble_delegate->GetAnchorRect().ToString());
1474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Testing that a move of the anchor view will lead to new bubble locations.
1504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_F(BubbleDelegateTest, TestAnchorRectMovesWithViewTest) {
1514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Create an anchor widget and add a view to be used as anchor view.
1524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  scoped_ptr<Widget> anchor_widget(CreateTestWidget());
1534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  TestBubbleDelegateView* bubble_delegate = new TestBubbleDelegateView(
1544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      anchor_widget->GetContentsView());
1554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  BubbleDelegateView::CreateBubble(bubble_delegate);
1564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  anchor_widget->GetContentsView()->SetBounds(10, 10, 100, 100);
1584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const gfx::Rect view_rect = bubble_delegate->GetAnchorRect();
1594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  anchor_widget->GetContentsView()->SetBounds(20, 10, 100, 100);
1614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const gfx::Rect view_rect_2 = bubble_delegate->GetAnchorRect();
1624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_NE(view_rect.ToString(), view_rect_2.ToString());
1634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(BubbleDelegateTest, ResetAnchorWidget) {
1663240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  scoped_ptr<Widget> anchor_widget(CreateTestWidget());
1673240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  BubbleDelegateView* bubble_delegate = new BubbleDelegateView(
1683240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      anchor_widget->GetContentsView(), BubbleBorder::NONE);
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure the bubble widget is parented to a widget other than the anchor
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // widget so that closing the anchor widget does not close the bubble widget.
1723240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  scoped_ptr<Widget> parent_widget(CreateTestWidget());
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bubble_delegate->set_parent_window(parent_widget->GetNativeView());
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Preventing close on deactivate should not prevent closing with the parent.
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bubble_delegate->set_close_on_deactivate(false);
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* bubble_widget = BubbleDelegateView::CreateBubble(bubble_delegate);
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(bubble_delegate, bubble_widget->widget_delegate());
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(bubble_widget, bubble_delegate->GetWidget());
1793240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  EXPECT_EQ(anchor_widget, bubble_delegate->anchor_widget());
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  test::TestWidgetObserver bubble_observer(bubble_widget);
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(bubble_observer.widget_closed());
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Showing and hiding the bubble widget should have no effect on its anchor.
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bubble_widget->Show();
1853240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  EXPECT_EQ(anchor_widget, bubble_delegate->anchor_widget());
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bubble_widget->Hide();
1873240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  EXPECT_EQ(anchor_widget, bubble_delegate->anchor_widget());
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that closing the anchor widget clears the bubble's reference to that
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // anchor widget, but the bubble itself does not close.
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  anchor_widget->CloseNow();
1923240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  EXPECT_NE(anchor_widget, bubble_delegate->anchor_widget());
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(bubble_observer.widget_closed());
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(msw): Remove activation hack to prevent bookkeeping errors in:
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //            aura::test::TestActivationClient::OnWindowDestroyed().
1973240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  scoped_ptr<Widget> smoke_and_mirrors_widget(CreateTestWidget());
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(bubble_observer.widget_closed());
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that closing the parent widget also closes the bubble itself.
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  parent_widget->CloseNow();
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(bubble_observer.widget_closed());
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2053240926e260ce088908e02ac07a6cf7b0c0cbf44Ben MurdochTEST_F(BubbleDelegateTest, InitiallyFocusedView) {
2063240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  scoped_ptr<Widget> anchor_widget(CreateTestWidget());
2073240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  BubbleDelegateView* bubble_delegate = new BubbleDelegateView(
2083240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      anchor_widget->GetContentsView(), BubbleBorder::NONE);
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget* bubble_widget = BubbleDelegateView::CreateBubble(bubble_delegate);
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(bubble_delegate->GetInitiallyFocusedView(),
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            bubble_widget->GetFocusManager()->GetFocusedView());
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bubble_widget->CloseNow();
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2153240926e260ce088908e02ac07a6cf7b0c0cbf44Ben MurdochTEST_F(BubbleDelegateTest, NonClientHitTest) {
2163240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  scoped_ptr<Widget> anchor_widget(CreateTestWidget());
2173240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  TestBubbleDelegateView* bubble_delegate =
2183240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      new TestBubbleDelegateView(anchor_widget->GetContentsView());
2193240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  BubbleDelegateView::CreateBubble(bubble_delegate);
2203240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  BubbleFrameView* frame = bubble_delegate->GetBubbleFrameView();
2213240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  const int border = frame->bubble_border()->GetBorderThickness();
2223240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
2233240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  struct {
2243240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    const int point;
2253240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    const int hit;
2263240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  } cases[] = {
2273240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    { border,      HTNOWHERE },
2283240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    { border + 50, HTCLIENT  },
2293240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    { 1000,        HTNOWHERE },
2303240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  };
2313240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
2323240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
2333240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    gfx::Point point(cases[i].point, cases[i].point);
2343240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    EXPECT_EQ(cases[i].hit, frame->NonClientHitTest(point))
2353240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch        << " with border: " << border << ", at point " << cases[i].point;
2363240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  }
2373240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch}
2383240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
239010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)TEST_F(BubbleDelegateTest, VisibleWhenAnchorWidgetBoundsChanged) {
240a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  scoped_ptr<Widget> anchor_widget(CreateTestWidget());
241a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  BubbleDelegateView* bubble_delegate = new BubbleDelegateView(
242a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      anchor_widget->GetContentsView(), BubbleBorder::NONE);
243a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  Widget* bubble_widget = BubbleDelegateView::CreateBubble(bubble_delegate);
244a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  test::TestWidgetObserver bubble_observer(bubble_widget);
245a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_FALSE(bubble_observer.widget_closed());
246a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
247a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  bubble_widget->Show();
248a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_TRUE(bubble_widget->IsVisible());
249a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  anchor_widget->SetBounds(gfx::Rect(10, 10, 100, 100));
250010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  EXPECT_TRUE(bubble_widget->IsVisible());
251a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
252a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Test that setting WidgetDelegate::set_can_activate() to false makes the
2545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// widget created via BubbleDelegateView::CreateBubble() not activatable.
2555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)TEST_F(BubbleDelegateTest, NotActivatable) {
2565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  scoped_ptr<Widget> anchor_widget(CreateTestWidget());
2575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  BubbleDelegateView* bubble_delegate = new BubbleDelegateView(
2585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      anchor_widget->GetContentsView(), BubbleBorder::NONE);
2595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  bubble_delegate->set_can_activate(false);
2605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  Widget* bubble_widget = BubbleDelegateView::CreateBubble(bubble_delegate);
2615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  bubble_widget->Show();
2625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_FALSE(bubble_widget->CanActivate());
2635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace views
266