15b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project// Use of this source code is governed by a BSD-style license that can be
35b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project// found in the LICENSE file.
45b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
55b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#include "base/basictypes.h"
65b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#include "base/strings/utf_string_conversions.h"
75b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#include "ui/base/ui_base_types.h"
85b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#include "ui/views/controls/button/label_button.h"
95b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#include "ui/views/test/test_views.h"
105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#include "ui/views/test/views_test_base.h"
115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#include "ui/views/widget/widget.h"
125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#include "ui/views/window/dialog_client_view.h"
135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#include "ui/views/window/dialog_delegate.h"
145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectnamespace views {
165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectclass TestDialogClientView : public DialogClientView {
185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project public:
195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  TestDialogClientView(View* contents_view,
205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project                       DialogDelegate* dialog_delegate)
215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      : DialogClientView(contents_view),
225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project        dialog_(dialog_delegate) {}
235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  virtual ~TestDialogClientView() {}
245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  // DialogClientView implementation.
265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  virtual DialogDelegate* GetDialogDelegate() const OVERRIDE { return dialog_; }
275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  View* GetContentsView() { return contents_view(); }
295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  void CreateExtraViews() {
315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    CreateExtraView();
325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    CreateFootnoteView();
335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  }
345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project private:
365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  DialogDelegate* dialog_;
375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  DISALLOW_COPY_AND_ASSIGN(TestDialogClientView);
395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project};
405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectclass DialogClientViewTest : public ViewsTestBase,
425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project                             public DialogDelegateView {
435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project public:
445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  DialogClientViewTest()
455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      : dialog_buttons_(ui::DIALOG_BUTTON_NONE),
465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project        extra_view_(NULL),
475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project        footnote_view_(NULL) {}
485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  virtual ~DialogClientViewTest() {}
495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  // testing::Test implementation.
515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  virtual void SetUp() OVERRIDE {
525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    dialog_buttons_ = ui::DIALOG_BUTTON_NONE;
535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    contents_.reset(new StaticSizedView(gfx::Size(100, 200)));
545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    client_view_.reset(new TestDialogClientView(contents_.get(), this));
555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    ViewsTestBase::SetUp();
575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  }
585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  // DialogDelegateView implementation.
605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  virtual View* GetContentsView() OVERRIDE { return contents_.get(); }
615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  virtual View* CreateExtraView() OVERRIDE { return extra_view_; }
625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  virtual View* CreateFootnoteView() OVERRIDE { return footnote_view_; }
635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  virtual int GetDialogButtons() const OVERRIDE { return dialog_buttons_; }
645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project protected:
665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  gfx::Rect GetUpdatedClientBounds() {
675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    client_view_->SizeToPreferredSize();
685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    client_view_->Layout();
695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    return client_view_->bounds();
705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  }
715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  // Makes sure that the content view is sized correctly. Width must be at least
735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  // the requested amount, but height should always match exactly.
745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  void CheckContentsIsSetToPreferredSize() {
755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    const gfx::Rect client_bounds = GetUpdatedClientBounds();
765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    const gfx::Size preferred_size = contents_->GetPreferredSize();
775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    EXPECT_EQ(preferred_size.height(), contents_->bounds().height());
785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    EXPECT_LE(preferred_size.width(), contents_->bounds().width());
795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    EXPECT_EQ(contents_->bounds().origin(), client_bounds.origin());
805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    EXPECT_EQ(contents_->bounds().right(), client_bounds.right());
815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  }
825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  // Sets the buttons to show in the dialog and refreshes the dialog.
845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  void SetDialogButtons(int dialog_buttons) {
855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    dialog_buttons_ = dialog_buttons;
865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    client_view_->UpdateDialogButtons();
875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  }
885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  // Sets the extra view.
905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  void SetExtraView(View* view) {
915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    DCHECK(!extra_view_);
925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    extra_view_ = view;
935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    client_view_->CreateExtraViews();
945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  }
955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  // Sets the footnote view.
975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  void SetFootnoteView(View* view) {
985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    DCHECK(!footnote_view_);
995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    footnote_view_ = view;
1005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    client_view_->CreateExtraViews();
1015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  }
1025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  TestDialogClientView* client_view() { return client_view_.get(); }
1045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project private:
1065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  // The contents of the dialog.
1075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  scoped_ptr<View> contents_;
1085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  // The DialogClientView that's being tested.
1095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  scoped_ptr<TestDialogClientView> client_view_;
1105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  // The bitmask of buttons to show in the dialog.
1115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  int dialog_buttons_;
1125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  View* extra_view_;  // weak
1135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  View* footnote_view_;  // weak
1145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  DISALLOW_COPY_AND_ASSIGN(DialogClientViewTest);
1165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project};
1175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source ProjectTEST_F(DialogClientViewTest, UpdateButtons) {
1195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  // This dialog should start with no buttons.
1205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  EXPECT_EQ(GetDialogButtons(), ui::DIALOG_BUTTON_NONE);
1215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  EXPECT_EQ(NULL, client_view()->ok_button());
1225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  EXPECT_EQ(NULL, client_view()->cancel_button());
1235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  const int height_without_buttons = GetUpdatedClientBounds().height();
1245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  // Update to use both buttons.
1265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  SetDialogButtons(ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL);
1275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  EXPECT_TRUE(client_view()->ok_button()->is_default());
1285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  EXPECT_FALSE(client_view()->cancel_button()->is_default());
1295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  const int height_with_buttons = GetUpdatedClientBounds().height();
1305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  EXPECT_GT(height_with_buttons, height_without_buttons);
1315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  // Remove the dialog buttons.
1335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  SetDialogButtons(ui::DIALOG_BUTTON_NONE);
1345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  EXPECT_EQ(NULL, client_view()->ok_button());
1355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  EXPECT_EQ(NULL, client_view()->cancel_button());
1365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  EXPECT_EQ(GetUpdatedClientBounds().height(), height_without_buttons);
1375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  // Reset with just an ok button.
1395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  SetDialogButtons(ui::DIALOG_BUTTON_OK);
1405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  EXPECT_TRUE(client_view()->ok_button()->is_default());
1415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  EXPECT_EQ(NULL, client_view()->cancel_button());
1425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  EXPECT_EQ(GetUpdatedClientBounds().height(), height_with_buttons);
1435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  // Reset with just a cancel button.
1455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  SetDialogButtons(ui::DIALOG_BUTTON_CANCEL);
1465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  EXPECT_EQ(NULL, client_view()->ok_button());
1475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  EXPECT_TRUE(client_view()->cancel_button()->is_default());
1485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  EXPECT_EQ(GetUpdatedClientBounds().height(), height_with_buttons);
1495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
1505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source ProjectTEST_F(DialogClientViewTest, RemoveAndUpdateButtons) {
1525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  // Removing buttons from another context should clear the local pointer.
1535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  SetDialogButtons(ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL);
1545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  delete client_view()->ok_button();
1555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  EXPECT_EQ(NULL, client_view()->ok_button());
1565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  delete client_view()->cancel_button();
1575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  EXPECT_EQ(NULL, client_view()->cancel_button());
1585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  // Updating should restore the requested buttons properly.
1605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  SetDialogButtons(ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL);
1615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  EXPECT_TRUE(client_view()->ok_button()->is_default());
1625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  EXPECT_FALSE(client_view()->cancel_button()->is_default());
1635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
1645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project// Test that the contents view gets its preferred size in the basic dialog
1665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project// configuration.
1675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source ProjectTEST_F(DialogClientViewTest, ContentsSize) {
1685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  CheckContentsIsSetToPreferredSize();
169  EXPECT_EQ(GetContentsView()->bounds().bottom(),
170            client_view()->bounds().bottom());
171}
172
173// Test the effect of the button strip on layout.
174TEST_F(DialogClientViewTest, LayoutWithButtons) {
175  SetDialogButtons(ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL);
176  CheckContentsIsSetToPreferredSize();
177  EXPECT_LT(GetContentsView()->bounds().bottom(),
178            client_view()->bounds().bottom());
179  gfx::Size no_extra_view_size = client_view()->bounds().size();
180
181  View* extra_view = new StaticSizedView(gfx::Size(200, 200));
182  SetExtraView(extra_view);
183  CheckContentsIsSetToPreferredSize();
184  EXPECT_GT(client_view()->bounds().height(), no_extra_view_size.height());
185  int width_of_extra_view = extra_view->bounds().width();
186
187  // Visibility of extra view is respected.
188  extra_view->SetVisible(false);
189  CheckContentsIsSetToPreferredSize();
190  EXPECT_EQ(no_extra_view_size.height(), client_view()->bounds().height());
191  EXPECT_EQ(no_extra_view_size.width(), client_view()->bounds().width());
192
193  // Try with a reduced-size dialog.
194  extra_view->SetVisible(true);
195  client_view()->SetBoundsRect(gfx::Rect(gfx::Point(0, 0), no_extra_view_size));
196  client_view()->Layout();
197  DCHECK_GT(width_of_extra_view, extra_view->bounds().width());
198}
199
200// Test the effect of the footnote view on layout.
201TEST_F(DialogClientViewTest, LayoutWithFootnote) {
202  CheckContentsIsSetToPreferredSize();
203  gfx::Size no_footnote_size = client_view()->bounds().size();
204
205  View* footnote_view = new StaticSizedView(gfx::Size(200, 200));
206  SetFootnoteView(footnote_view);
207  CheckContentsIsSetToPreferredSize();
208  EXPECT_GT(client_view()->bounds().height(), no_footnote_size.height());
209  EXPECT_EQ(200, footnote_view->bounds().height());
210  gfx::Size with_footnote_size = client_view()->bounds().size();
211  EXPECT_EQ(with_footnote_size.width(), footnote_view->bounds().width());
212
213  SetDialogButtons(ui::DIALOG_BUTTON_CANCEL);
214  CheckContentsIsSetToPreferredSize();
215  EXPECT_LE(with_footnote_size.height(), client_view()->bounds().height());
216  EXPECT_LE(with_footnote_size.width(), client_view()->bounds().width());
217  gfx::Size with_footnote_and_button_size = client_view()->bounds().size();
218
219  SetDialogButtons(ui::DIALOG_BUTTON_NONE);
220  footnote_view->SetVisible(false);
221  CheckContentsIsSetToPreferredSize();
222  EXPECT_EQ(no_footnote_size.height(), client_view()->bounds().height());
223  EXPECT_EQ(no_footnote_size.width(), client_view()->bounds().width());
224}
225
226// Test that GetHeightForWidth is respected for the footnote view.
227TEST_F(DialogClientViewTest, LayoutWithFootnoteHeightForWidth) {
228  CheckContentsIsSetToPreferredSize();
229  gfx::Size no_footnote_size = client_view()->bounds().size();
230
231  View* footnote_view = new ProportionallySizedView(3);
232  SetFootnoteView(footnote_view);
233  CheckContentsIsSetToPreferredSize();
234  EXPECT_GT(client_view()->bounds().height(), no_footnote_size.height());
235  EXPECT_EQ(footnote_view->bounds().width() * 3,
236            footnote_view->bounds().height());
237}
238
239// Test that the DialogClientView's FocusManager is properly updated when the
240// DialogClientView belongs to a non top level widget and the widget is
241// reparented. The DialogClientView belongs to a non top level widget in the
242// case of constrained windows. The constrained window's widget is reparented
243// when a browser tab is dragged to a different browser window.
244TEST_F(DialogClientViewTest, FocusManager) {
245  scoped_ptr<Widget> toplevel1(new Widget);
246  Widget::InitParams toplevel1_params =
247      CreateParams(Widget::InitParams::TYPE_WINDOW);
248  toplevel1_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
249  toplevel1->Init(toplevel1_params);
250
251  scoped_ptr<Widget> toplevel2(new Widget);
252  Widget::InitParams toplevel2_params =
253      CreateParams(Widget::InitParams::TYPE_WINDOW);
254  toplevel2_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
255  toplevel2->Init(toplevel2_params);
256
257  Widget* dialog = new Widget;
258  Widget::InitParams dialog_params =
259      CreateParams(Widget::InitParams::TYPE_WINDOW);
260  dialog_params.child = true;
261  dialog_params.delegate = new DialogDelegateView();
262  dialog_params.parent = toplevel1->GetNativeView();
263  dialog->Init(dialog_params);
264
265  // Test that the FocusManager has been properly set when the DialogClientView
266  // was parented to |dialog|.
267  DialogClientView* client_view =
268      static_cast<DialogClientView*>(dialog->client_view());
269  EXPECT_EQ(toplevel1->GetFocusManager(), client_view->focus_manager_);
270
271  // Test that the FocusManager is properly updated when the DialogClientView's
272  // top level widget is changed.
273  Widget::ReparentNativeView(dialog->GetNativeView(), NULL);
274  EXPECT_EQ(NULL, client_view->focus_manager_);
275  Widget::ReparentNativeView(dialog->GetNativeView(),
276                             toplevel2->GetNativeView());
277  EXPECT_EQ(toplevel2->GetFocusManager(), client_view->focus_manager_);
278  Widget::ReparentNativeView(dialog->GetNativeView(),
279                             toplevel1->GetNativeView());
280  EXPECT_NE(toplevel1->GetFocusManager(), toplevel2->GetFocusManager());
281  EXPECT_EQ(toplevel1->GetFocusManager(), client_view->focus_manager_);
282
283  // Test that the FocusManager is properly cleared when the DialogClientView is
284  // removed from |dialog| during the widget's destruction.
285  client_view->set_owned_by_client();
286  scoped_ptr<DialogClientView> owned_client_view(client_view);
287  toplevel1->CloseNow();
288  toplevel2->CloseNow();
289  EXPECT_EQ(NULL, owned_client_view->focus_manager_);
290}
291
292}  // namespace views
293