1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "base/bind.h"
6#include "base/run_loop.h"
7#include "base/strings/utf_string_conversions.h"
8#include "chrome/browser/media/fake_desktop_media_list.h"
9#include "chrome/browser/ui/views/desktop_media_picker_views.h"
10#include "components/web_modal/test_web_contents_modal_dialog_host.h"
11#include "content/public/test/test_browser_thread_bundle.h"
12#include "testing/gmock/include/gmock/gmock.h"
13#include "testing/gtest/include/gtest/gtest.h"
14#include "ui/aura/window.h"
15#include "ui/compositor/test/context_factories_for_test.h"
16#include "ui/views/test/views_test_helper.h"
17#include "ui/views/widget/widget.h"
18#include "ui/views/window/dialog_delegate.h"
19
20namespace views {
21
22class DesktopMediaPickerViewsTest : public testing::Test {
23 public:
24  DesktopMediaPickerViewsTest() {}
25  virtual ~DesktopMediaPickerViewsTest() {}
26
27  virtual void SetUp() OVERRIDE {
28    bool enable_pixel_output = false;
29    ui::ContextFactory* context_factory =
30        ui::InitializeContextFactoryForTests(enable_pixel_output);
31    test_helper_.reset(
32        ViewsTestHelper::Create(base::MessageLoopForUI::current(),
33                                context_factory));
34    test_helper_->SetUp();
35
36    Widget::InitParams params(Widget::InitParams::TYPE_WINDOW);
37    params.context = test_helper_->GetContext();
38    params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
39    parent_widget_.reset(new Widget);
40    parent_widget_->Init(params);
41
42    media_list_ = new FakeDesktopMediaList();
43    scoped_ptr<FakeDesktopMediaList> media_list(media_list_);
44
45    base::string16 app_name = base::ASCIIToUTF16("foo");
46
47    picker_views_.reset(new DesktopMediaPickerViews());
48    picker_views_->Show(NULL,
49                        parent_widget_->GetNativeWindow(),
50                        NULL,
51                        app_name,
52                        app_name,
53                        media_list.PassAs<DesktopMediaList>(),
54                        base::Bind(&DesktopMediaPickerViewsTest::OnPickerDone,
55                                   base::Unretained(this)));
56  }
57
58  virtual void TearDown() OVERRIDE {
59    test_helper_->TearDown();
60    ui::TerminateContextFactoryForTests();
61  }
62
63  DesktopMediaPickerDialogView* GetPickerDialogView() const {
64    return picker_views_->GetDialogViewForTesting();
65  }
66
67  MOCK_METHOD1(OnPickerDone, void(content::DesktopMediaID));
68
69 protected:
70  content::TestBrowserThreadBundle thread_bundle_;
71  scoped_ptr<views::ViewsTestHelper> test_helper_;
72  FakeDesktopMediaList* media_list_;
73  scoped_ptr<Widget> parent_widget_;
74  scoped_ptr<DesktopMediaPickerViews> picker_views_;
75};
76
77TEST_F(DesktopMediaPickerViewsTest, DoneCallbackCalledWhenWindowClosed) {
78  EXPECT_CALL(*this, OnPickerDone(content::DesktopMediaID()));
79
80  GetPickerDialogView()->GetWidget()->Close();
81  base::RunLoop().RunUntilIdle();
82}
83
84TEST_F(DesktopMediaPickerViewsTest, DoneCallbackCalledOnOkButtonPressed) {
85  const int kFakeId = 222;
86  EXPECT_CALL(*this,
87              OnPickerDone(content::DesktopMediaID(
88                  content::DesktopMediaID::TYPE_WINDOW, kFakeId)));
89
90  media_list_->AddSource(kFakeId);
91
92  EXPECT_FALSE(
93      GetPickerDialogView()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_OK));
94
95  GetPickerDialogView()->GetMediaSourceViewForTesting(0)->OnFocus();
96  EXPECT_TRUE(
97      GetPickerDialogView()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_OK));
98
99  GetPickerDialogView()->Accept();
100  base::RunLoop().RunUntilIdle();
101}
102
103TEST_F(DesktopMediaPickerViewsTest, DoneCallbackCalledOnDoubleClick) {
104  const int kFakeId = 222;
105  EXPECT_CALL(*this,
106              OnPickerDone(content::DesktopMediaID(
107                  content::DesktopMediaID::TYPE_WINDOW, kFakeId)));
108
109  media_list_->AddSource(kFakeId);
110
111  ui::MouseEvent double_click(ui::ET_MOUSE_PRESSED,
112                              gfx::Point(),
113                              gfx::Point(),
114                              ui::EF_LEFT_MOUSE_BUTTON | ui::EF_IS_DOUBLE_CLICK,
115                              ui::EF_LEFT_MOUSE_BUTTON);
116
117  GetPickerDialogView()->GetMediaSourceViewForTesting(0)->OnMousePressed(
118      double_click);
119  base::RunLoop().RunUntilIdle();
120}
121
122TEST_F(DesktopMediaPickerViewsTest, DoneCallbackCalledOnDoubleTap) {
123  const int kFakeId = 222;
124  EXPECT_CALL(*this,
125              OnPickerDone(content::DesktopMediaID(
126                  content::DesktopMediaID::TYPE_WINDOW, kFakeId)));
127
128  media_list_->AddSource(kFakeId);
129  ui::GestureEventDetails details(ui::ET_GESTURE_TAP);
130  details.set_tap_count(2);
131  ui::GestureEvent double_tap(10, 10, 0, base::TimeDelta(), details);
132
133  GetPickerDialogView()->GetMediaSourceViewForTesting(0)->OnGestureEvent(
134      &double_tap);
135  base::RunLoop().RunUntilIdle();
136}
137
138TEST_F(DesktopMediaPickerViewsTest, CancelButtonAlwaysEnabled) {
139  EXPECT_TRUE(
140      GetPickerDialogView()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_CANCEL));
141}
142
143// Verifies that the MediaSourceView is added or removed when |media_list_| is
144// updated.
145TEST_F(DesktopMediaPickerViewsTest, AddAndRemoveMediaSource) {
146  // No media source at first.
147  EXPECT_EQ(NULL, GetPickerDialogView()->GetMediaSourceViewForTesting(0));
148
149  for (int i = 0; i < 3; ++i) {
150    media_list_->AddSource(i);
151    EXPECT_TRUE(GetPickerDialogView()->GetMediaSourceViewForTesting(i));
152  }
153
154  for (int i = 2; i >= 0; --i) {
155    media_list_->RemoveSource(i);
156    EXPECT_EQ(NULL, GetPickerDialogView()->GetMediaSourceViewForTesting(i));
157  }
158}
159
160// Verifies that focusing the MediaSourceView marks it selected and the
161// original selected MediaSourceView gets unselected.
162TEST_F(DesktopMediaPickerViewsTest, FocusMediaSourceViewToSelect) {
163  media_list_->AddSource(0);
164  media_list_->AddSource(1);
165
166  DesktopMediaSourceView* source_view_0 =
167      GetPickerDialogView()->GetMediaSourceViewForTesting(0);
168
169  DesktopMediaSourceView* source_view_1 =
170      GetPickerDialogView()->GetMediaSourceViewForTesting(1);
171
172  EXPECT_FALSE(source_view_0->is_selected());
173  EXPECT_FALSE(source_view_1->is_selected());
174
175  source_view_0->OnFocus();
176  EXPECT_TRUE(source_view_0->is_selected());
177
178  // Removing the focus does not undo the selection.
179  source_view_0->OnBlur();
180  EXPECT_TRUE(source_view_0->is_selected());
181
182  source_view_1->OnFocus();
183  EXPECT_FALSE(source_view_0->is_selected());
184  EXPECT_TRUE(source_view_1->is_selected());
185}
186
187TEST_F(DesktopMediaPickerViewsTest, OkButtonDisabledWhenNoSelection) {
188  media_list_->AddSource(111);
189
190  EXPECT_FALSE(
191      GetPickerDialogView()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_OK));
192
193  GetPickerDialogView()->GetMediaSourceViewForTesting(0)->OnFocus();
194  EXPECT_TRUE(
195      GetPickerDialogView()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_OK));
196
197  media_list_->RemoveSource(0);
198  EXPECT_FALSE(
199      GetPickerDialogView()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_OK));
200}
201
202}  // namespace views
203