Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(267)

Side by Side Diff: chrome/browser/ui/views/toolbar/toolbar_action_view_unittest.cc

Issue 888043003: [Extensions Toolbar Views] Add a ToolbarActionView unittest (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Latest master Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « chrome/browser/ui/views/toolbar/toolbar_action_view.cc ('k') | chrome/chrome_tests_unit.gypi » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2015 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/run_loop.h"
6 #include "base/strings/string16.h"
7 #include "base/strings/utf_string_conversions.h"
8 #include "chrome/browser/sessions/session_tab_helper.h"
9 #include "chrome/browser/ui/toolbar/test_toolbar_action_view_controller.h"
10 #include "chrome/browser/ui/toolbar/toolbar_action_view_controller.h"
11 #include "chrome/browser/ui/views/toolbar/toolbar_action_view.h"
12 #include "chrome/test/base/testing_profile.h"
13 #include "content/public/test/test_browser_thread.h"
14 #include "content/public/test/test_renderer_host.h"
15 #include "content/public/test/web_contents_tester.h"
16 #include "ui/accessibility/ax_view_state.h"
17 #include "ui/events/test/event_generator.h"
18 #include "ui/views/test/views_test_base.h"
19
20 #if defined(USE_AURA)
21 #include "ui/aura/env.h"
22 #endif
23
24 namespace {
25
26 // A helper class to create test web contents (tabs) for unit tests, without
27 // inheriting from RenderViewTestHarness. Can create web contents, and will
28 // clean up after itself upon destruction. Owns all created web contents.
29 // A few notes:
30 // - Works well allocated on the stack, because it should be destroyed before
31 // associated browser context.
32 // - Doesn't play nice with web contents created any other way (because of
33 // the implementation of RenderViewHostTestEnabler). But if you are creating
34 // web contents already, what do you need this for? ;)
35 // TODO(devlin): Look around and see if this class is needed elsewhere; if so,
36 // move it there and expand the API a bit (methods to, e.g., delete/close a
37 // web contents, access existing web contents, etc).
38 class TestWebContentsFactory {
39 public:
40 // |init_aura| initializes the aura environment (and cleans it up at
41 // shutdown, which is necessary for web contents. Since this method should
42 // only be called once, this should only be true if no other part of the test
43 // has initialized the environment.
44 explicit TestWebContentsFactory(bool init_aura);
45 ~TestWebContentsFactory();
46
47 // Creates a new WebContents with the given |context|, and returns it.
48 content::WebContents* CreateWebContents(content::BrowserContext* context);
49 private:
50 // The test factory (and friends) for creating test web contents.
51 scoped_ptr<content::RenderViewHostTestEnabler> rvh_enabler_;
52 // The vector of web contents that this class created.
53 ScopedVector<content::WebContents> web_contents_;
54
55 // True if the factory initialized aura (and should thus tear it down).
56 bool init_aura_;
57
58 DISALLOW_COPY_AND_ASSIGN(TestWebContentsFactory);
59 };
60
61 TestWebContentsFactory::TestWebContentsFactory(bool init_aura)
62 : rvh_enabler_(new content::RenderViewHostTestEnabler()),
63 init_aura_(init_aura) {
64 #if defined(USE_AURA)
65 if (init_aura)
66 aura::Env::CreateInstance(true);
67 #endif
68 }
69
70 TestWebContentsFactory::~TestWebContentsFactory() {
71 web_contents_.clear();
72 // Let any posted tasks for web contents deletion run.
73 base::RunLoop().RunUntilIdle();
74 rvh_enabler_.reset();
75 // Let any posted tasks for RenderProcess/ViewHost deletion run.
76 base::RunLoop().RunUntilIdle();
77 #if defined(USE_AURA)
78 if (init_aura_)
79 aura::Env::DeleteInstance();
80 #endif
81 }
82
83 content::WebContents* TestWebContentsFactory::CreateWebContents(
84 content::BrowserContext* context) {
85 scoped_ptr<content::WebContents> web_contents(
86 content::WebContentsTester::CreateTestWebContents(context, nullptr));
87 DCHECK(web_contents);
88 web_contents_.push_back(web_contents.release());
89 return web_contents_.back();
90 }
91
92 // A test delegate for a toolbar action view.
93 class TestToolbarActionViewDelegate : public ToolbarActionView::Delegate {
94 public:
95 TestToolbarActionViewDelegate() : shown_in_menu_(false),
96 overflow_reference_view_(nullptr),
97 web_contents_(nullptr) {}
98 ~TestToolbarActionViewDelegate() override {}
99
100 // ToolbarActionView::Delegate:
101 content::WebContents* GetCurrentWebContents() override {
102 return web_contents_;
103 }
104 bool ShownInsideMenu() const override { return shown_in_menu_; }
105 void OnToolbarActionViewDragDone() override {}
106 views::MenuButton* GetOverflowReferenceView() override {
107 return overflow_reference_view_;
108 }
109 void SetPopupOwner(ToolbarActionView* popup_owner) override {}
110 ToolbarActionView* GetMainViewForAction(ToolbarActionView* view) override {
111 return nullptr;
112 }
113 void WriteDragDataForView(views::View* sender,
114 const gfx::Point& press_pt,
115 ui::OSExchangeData* data) override {}
116 int GetDragOperationsForView(views::View* sender,
117 const gfx::Point& p) override {
118 return ui::DragDropTypes::DRAG_NONE;
119 }
120 bool CanStartDragForView(views::View* sender,
121 const gfx::Point& press_pt,
122 const gfx::Point& p) override { return false; }
123
124 void set_shown_in_menu(bool shown_in_menu) { shown_in_menu_ = shown_in_menu; }
125 void set_overflow_reference_view(views::MenuButton* overflow_reference_view) {
126 overflow_reference_view_ = overflow_reference_view;
127 }
128 void set_web_contents(content::WebContents* web_contents) {
129 web_contents_ = web_contents;
130 }
131
132 private:
133 bool shown_in_menu_;
134
135 views::MenuButton* overflow_reference_view_;
136
137 content::WebContents* web_contents_;
138
139 DISALLOW_COPY_AND_ASSIGN(TestToolbarActionViewDelegate);
140 };
141
142 } // namespace
143
144 class ToolbarActionViewUnitTest : public views::ViewsTestBase {
145 public:
146 ToolbarActionViewUnitTest()
147 : widget_(nullptr),
148 ui_thread_(content::BrowserThread::UI, message_loop()) {}
149 ~ToolbarActionViewUnitTest() override {}
150
151 void SetUp() override {
152 views::ViewsTestBase::SetUp();
153
154 widget_ = new views::Widget;
155 views::Widget::InitParams params =
156 CreateParams(views::Widget::InitParams::TYPE_WINDOW_FRAMELESS);
157 params.bounds = gfx::Rect(0, 0, 200, 200);
158 widget_->Init(params);
159 }
160 void TearDown() override {
161 if (!widget_->IsClosed())
162 widget_->Close();
163 views::ViewsTestBase::TearDown();
164 }
165
166 views::Widget* widget() { return widget_; }
167
168 private:
169 // The widget managed by this test.
170 views::Widget* widget_;
171
172 // Web contents need a fake ui thread.
173 content::TestBrowserThread ui_thread_;
174
175 DISALLOW_COPY_AND_ASSIGN(ToolbarActionViewUnitTest);
176 };
177
178 // Test the basic ui of a ToolbarActionView and that it responds correctly to
179 // a controller's state.
180 TEST_F(ToolbarActionViewUnitTest, BasicToolbarActionViewTest) {
181 TestingProfile profile;
182
183 // ViewsTestBase initializees the aura environment, so the factory shouldn't.
184 TestWebContentsFactory web_contents_factory(false);
185
186 TestToolbarActionViewController controller("fake controller");
187 TestToolbarActionViewDelegate action_view_delegate;
188
189 // Configure the test controller and delegate.
190 base::string16 name = base::ASCIIToUTF16("name");
191 controller.SetAccessibleName(name);
192 base::string16 tooltip = base::ASCIIToUTF16("tooltip");
193 controller.SetTooltip(tooltip);
194 content::WebContents* web_contents =
195 web_contents_factory.CreateWebContents(&profile);
196 SessionTabHelper::CreateForWebContents(web_contents);
197 action_view_delegate.set_web_contents(web_contents);
198
199 // Move the mouse off the not-yet-existent button.
200 ui::test::EventGenerator generator(GetContext(), widget()->GetNativeWindow());
201 generator.MoveMouseTo(gfx::Point(300, 300));
202
203 // Create a new toolbar action view.
204 ToolbarActionView view(&controller, &profile, &action_view_delegate);
205 view.set_owned_by_client();
206 view.SetBoundsRect(gfx::Rect(0, 0, 200, 20));
207 widget()->SetContentsView(&view);
208 widget()->Show();
209
210 // Check that the tooltip and accessible state of the view match the
211 // controller's.
212 base::string16 tooltip_test;
213 EXPECT_TRUE(view.GetTooltipText(gfx::Point(), &tooltip_test));
214 EXPECT_EQ(tooltip, tooltip_test);
215 ui::AXViewState ax_state;
216 view.GetAccessibleState(&ax_state);
217 EXPECT_EQ(name, ax_state.name);
218
219 // The button should start in normal state, with no actions executed.
220 EXPECT_EQ(views::Button::STATE_NORMAL, view.state());
221 EXPECT_EQ(0, controller.execute_action_count());
222
223 // Click the button. This should execute it.
224 generator.MoveMouseTo(gfx::Point(10, 10));
225 generator.ClickLeftButton();
226 EXPECT_EQ(1, controller.execute_action_count());
227
228 // Move the mouse off the button, and show a popup through a non-user action.
229 // Since this was not a user action, the button should not be pressed.
230 generator.MoveMouseTo(gfx::Point(300, 300));
231 controller.ShowPopup(false);
232 EXPECT_EQ(views::Button::STATE_NORMAL, view.state());
233 controller.HidePopup();
234
235 // Show the popup through a user action - the button should be pressed.
236 controller.ShowPopup(true);
237 EXPECT_EQ(views::Button::STATE_PRESSED, view.state());
238 controller.HidePopup();
239 EXPECT_EQ(views::Button::STATE_NORMAL, view.state());
240
241 // Ensure that the button's enabled state reflects that of the controller.
242 controller.SetEnabled(false);
243 EXPECT_EQ(views::Button::STATE_DISABLED, view.state());
244 controller.SetEnabled(true);
245 EXPECT_EQ(views::Button::STATE_NORMAL, view.state());
246
247 // Ensure that the button's want-to-run state reflects that of the controller.
248 controller.SetWantsToRun(true);
249 EXPECT_TRUE(view.wants_to_run_for_testing());
250 controller.SetWantsToRun(false);
251 EXPECT_FALSE(view.wants_to_run_for_testing());
252
253 // Create an overflow button.
254 views::MenuButton overflow_button(nullptr, base::string16(), nullptr, false);
255 overflow_button.set_owned_by_client();
256 action_view_delegate.set_overflow_reference_view(&overflow_button);
257
258 // If the view isn't visible, the overflow button should be pressed for
259 // popups.
260 view.SetVisible(false);
261 controller.ShowPopup(true);
262 EXPECT_EQ(views::Button::STATE_NORMAL, view.state());
263 EXPECT_EQ(views::Button::STATE_PRESSED, overflow_button.state());
264 controller.HidePopup();
265 EXPECT_EQ(views::Button::STATE_NORMAL, view.state());
266 EXPECT_EQ(views::Button::STATE_NORMAL, overflow_button.state());
267 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/views/toolbar/toolbar_action_view.cc ('k') | chrome/chrome_tests_unit.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698