Revert of Add button to add new FSP services to Files app. (patchset #8 id:140001...
[chromium-blink-merge.git] / chrome / browser / ui / views / toolbar / browser_actions_container_browsertest.cc
blob9649b37b2b068df20f8e2e0e005afb70eaa0bc86
1 // Copyright 2013 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.
5 #include "chrome/browser/ui/views/toolbar/browser_actions_container.h"
7 #include "chrome/browser/extensions/api/extension_action/extension_action_api.h"
8 #include "chrome/browser/extensions/browser_action_test_util.h"
9 #include "chrome/browser/extensions/extension_toolbar_model.h"
10 #include "chrome/browser/ui/browser_window.h"
11 #include "chrome/browser/ui/toolbar/browser_actions_bar_browsertest.h"
12 #include "chrome/browser/ui/views/extensions/browser_action_drag_data.h"
13 #include "chrome/browser/ui/views/frame/browser_view.h"
14 #include "chrome/browser/ui/views/toolbar/toolbar_action_view.h"
15 #include "chrome/browser/ui/views/toolbar/toolbar_view.h"
16 #include "extensions/browser/extension_prefs.h"
17 #include "extensions/common/extension.h"
18 #include "ui/base/dragdrop/drop_target_event.h"
19 #include "ui/base/dragdrop/os_exchange_data.h"
20 #include "ui/gfx/geometry/point.h"
21 #include "ui/views/view.h"
23 // TODO(devlin): Continue moving any tests that should be platform independent
24 // from this file to the crossplatform tests in
25 // chrome/browser/ui/toolbar/browser_actions_bar_browsertest.cc.
27 // Test that dragging browser actions works, and that dragging a browser action
28 // from the overflow menu results in it "popping" out (growing the container
29 // size by 1), rather than just reordering the extensions.
30 IN_PROC_BROWSER_TEST_F(BrowserActionsBarBrowserTest, DragBrowserActions) {
31 LoadExtensions();
33 // Sanity check: All extensions showing; order is A B C.
34 EXPECT_EQ(3, browser_actions_bar()->VisibleBrowserActions());
35 EXPECT_EQ(3, browser_actions_bar()->NumberOfBrowserActions());
36 EXPECT_EQ(extension_a()->id(), browser_actions_bar()->GetExtensionId(0));
37 EXPECT_EQ(extension_b()->id(), browser_actions_bar()->GetExtensionId(1));
38 EXPECT_EQ(extension_c()->id(), browser_actions_bar()->GetExtensionId(2));
40 BrowserActionsContainer* container =
41 BrowserView::GetBrowserViewForBrowser(browser())
42 ->toolbar()->browser_actions();
44 // Simulate a drag and drop to the right.
45 ui::OSExchangeData drop_data;
46 // Drag extension A from index 0...
47 BrowserActionDragData browser_action_drag_data(extension_a()->id(), 0u);
48 browser_action_drag_data.Write(profile(), &drop_data);
49 ToolbarActionView* view = container->GetViewForId(extension_b()->id());
50 // ...to the right of extension B.
51 gfx::Point location(view->x() + view->width(), view->y());
52 ui::DropTargetEvent target_event(
53 drop_data, location, location, ui::DragDropTypes::DRAG_MOVE);
55 // Drag and drop.
56 container->OnDragUpdated(target_event);
57 container->OnPerformDrop(target_event);
59 // The order should now be B A C, since A was dragged to the right of B.
60 EXPECT_EQ(extension_b()->id(), browser_actions_bar()->GetExtensionId(0));
61 EXPECT_EQ(extension_a()->id(), browser_actions_bar()->GetExtensionId(1));
62 EXPECT_EQ(extension_c()->id(), browser_actions_bar()->GetExtensionId(2));
64 // This order should be reflected in the underlying model.
65 EXPECT_EQ(extension_b(), toolbar_model()->toolbar_items()[0].get());
66 EXPECT_EQ(extension_a(), toolbar_model()->toolbar_items()[1].get());
67 EXPECT_EQ(extension_c(), toolbar_model()->toolbar_items()[2].get());
69 // Simulate a drag and drop to the left.
70 ui::OSExchangeData drop_data2;
71 // Drag extension A from index 1...
72 BrowserActionDragData browser_action_drag_data2(extension_a()->id(), 1u);
73 browser_action_drag_data2.Write(profile(), &drop_data2);
74 // ...to the left of extension B (which is now at index 0).
75 location = gfx::Point(view->x(), view->y());
76 ui::DropTargetEvent target_event2(
77 drop_data2, location, location, ui::DragDropTypes::DRAG_MOVE);
79 // Drag and drop.
80 container->OnDragUpdated(target_event2);
81 container->OnPerformDrop(target_event2);
83 // Order should be restored to A B C.
84 EXPECT_EQ(extension_a()->id(), browser_actions_bar()->GetExtensionId(0));
85 EXPECT_EQ(extension_b()->id(), browser_actions_bar()->GetExtensionId(1));
86 EXPECT_EQ(extension_c()->id(), browser_actions_bar()->GetExtensionId(2));
88 // Shrink the size of the container so we have an overflow menu.
89 toolbar_model()->SetVisibleIconCount(2u);
90 EXPECT_EQ(2u, container->VisibleBrowserActions());
91 ASSERT_TRUE(container->chevron());
92 EXPECT_TRUE(container->chevron()->visible());
94 // Simulate a drag and drop from the overflow menu.
95 ui::OSExchangeData drop_data3;
96 // Drag extension C from index 2 (in the overflow menu)...
97 BrowserActionDragData browser_action_drag_data3(extension_c()->id(), 2u);
98 browser_action_drag_data3.Write(profile(), &drop_data3);
99 // ...to the left of extension B (which is back in index 1 on the main bar).
100 location = gfx::Point(view->x(), view->y());
101 ui::DropTargetEvent target_event3(
102 drop_data3, location, location, ui::DragDropTypes::DRAG_MOVE);
104 // Drag and drop.
105 container->OnDragUpdated(target_event3);
106 container->OnPerformDrop(target_event3);
108 // The order should have changed *and* the container should have grown to
109 // accommodate extension C. The new order should be A C B, and all three
110 // extensions should be visible, with no overflow menu.
111 EXPECT_EQ(extension_a()->id(), browser_actions_bar()->GetExtensionId(0));
112 EXPECT_EQ(extension_c()->id(), browser_actions_bar()->GetExtensionId(1));
113 EXPECT_EQ(extension_b()->id(), browser_actions_bar()->GetExtensionId(2));
114 EXPECT_EQ(3u, container->VisibleBrowserActions());
115 EXPECT_FALSE(container->chevron()->visible());
116 EXPECT_TRUE(toolbar_model()->all_icons_visible());
118 // TODO(devlin): Ideally, we'd also have tests for dragging from the legacy
119 // overflow menu (i.e., chevron) to the main bar, but this requires either
120 // having a fairly complicated interactive UI test or finding a good way to
121 // mock up the BrowserActionOverflowMenuController.
124 // Test that changes performed in one container affect containers in other
125 // windows so that it is consistent.
126 IN_PROC_BROWSER_TEST_F(BrowserActionsBarBrowserTest, MultipleWindows) {
127 LoadExtensions();
128 BrowserActionsContainer* first =
129 BrowserView::GetBrowserViewForBrowser(browser())->toolbar()->
130 browser_actions();
132 // Create a second browser.
133 Browser* second_browser = new Browser(
134 Browser::CreateParams(profile(), browser()->host_desktop_type()));
135 BrowserActionsContainer* second =
136 BrowserView::GetBrowserViewForBrowser(second_browser)->toolbar()->
137 browser_actions();
139 // Both containers should have the same order and visible actions, which
140 // is right now A B C.
141 EXPECT_EQ(3u, first->VisibleBrowserActions());
142 EXPECT_EQ(3u, second->VisibleBrowserActions());
143 EXPECT_EQ(extension_a()->id(), first->GetIdAt(0u));
144 EXPECT_EQ(extension_a()->id(), second->GetIdAt(0u));
145 EXPECT_EQ(extension_b()->id(), first->GetIdAt(1u));
146 EXPECT_EQ(extension_b()->id(), second->GetIdAt(1u));
147 EXPECT_EQ(extension_c()->id(), first->GetIdAt(2u));
148 EXPECT_EQ(extension_c()->id(), second->GetIdAt(2u));
150 // Simulate a drag and drop to the right.
151 ui::OSExchangeData drop_data;
152 // Drag extension A from index 0...
153 BrowserActionDragData browser_action_drag_data(extension_a()->id(), 0u);
154 browser_action_drag_data.Write(profile(), &drop_data);
155 ToolbarActionView* view = first->GetViewForId(extension_b()->id());
156 // ...to the right of extension B.
157 gfx::Point location(view->x() + view->width(), view->y());
158 ui::DropTargetEvent target_event(
159 drop_data, location, location, ui::DragDropTypes::DRAG_MOVE);
161 // Drag and drop.
162 first->OnDragUpdated(target_event);
163 first->OnPerformDrop(target_event);
165 // The new order, B A C, should be reflected in *both* containers, even
166 // though the drag only happened in the first one.
167 EXPECT_EQ(extension_b()->id(), first->GetIdAt(0u));
168 EXPECT_EQ(extension_b()->id(), second->GetIdAt(0u));
169 EXPECT_EQ(extension_a()->id(), first->GetIdAt(1u));
170 EXPECT_EQ(extension_a()->id(), second->GetIdAt(1u));
171 EXPECT_EQ(extension_c()->id(), first->GetIdAt(2u));
172 EXPECT_EQ(extension_c()->id(), second->GetIdAt(2u));
174 // Next, simulate a resize by shrinking the container.
175 first->OnResize(1, true);
176 // The first and second container should each have resized.
177 EXPECT_EQ(2u, first->VisibleBrowserActions());
178 EXPECT_EQ(2u, second->VisibleBrowserActions());
181 // Test that the BrowserActionsContainer responds correctly when the underlying
182 // model enters highlight mode, and that browser actions are undraggable in
183 // highlight mode. (Highlight mode itself it tested more thoroughly in the
184 // ExtensionToolbarModel browsertests).
185 IN_PROC_BROWSER_TEST_F(BrowserActionsBarBrowserTest, HighlightMode) {
186 LoadExtensions();
188 EXPECT_EQ(3, browser_actions_bar()->VisibleBrowserActions());
189 EXPECT_EQ(3, browser_actions_bar()->NumberOfBrowserActions());
191 BrowserActionsContainer* container =
192 BrowserView::GetBrowserViewForBrowser(browser())
193 ->toolbar()->browser_actions();
195 // Currently, dragging should be enabled.
196 ToolbarActionView* action_view = container->GetToolbarActionViewAt(0);
197 ASSERT_TRUE(action_view);
198 gfx::Point point(action_view->x(), action_view->y());
199 EXPECT_TRUE(container->CanStartDragForView(action_view, point, point));
201 extensions::ExtensionIdList extension_ids;
202 extension_ids.push_back(extension_a()->id());
203 extension_ids.push_back(extension_b()->id());
204 toolbar_model()->HighlightExtensions(extension_ids);
206 // Only two browser actions should be visible.
207 EXPECT_EQ(2, browser_actions_bar()->VisibleBrowserActions());
208 EXPECT_EQ(2, browser_actions_bar()->NumberOfBrowserActions());
210 // We shouldn't be able to drag in highlight mode.
211 action_view = container->GetToolbarActionViewAt(0);
212 EXPECT_FALSE(container->CanStartDragForView(action_view, point, point));
214 // We should go back to normal after leaving highlight mode.
215 toolbar_model()->StopHighlighting();
216 EXPECT_EQ(3, browser_actions_bar()->VisibleBrowserActions());
217 EXPECT_EQ(3, browser_actions_bar()->NumberOfBrowserActions());
218 action_view = container->GetToolbarActionViewAt(0);
219 EXPECT_TRUE(container->CanStartDragForView(action_view, point, point));
222 // Test the behavior of the overflow container for Extension Actions.
223 class BrowserActionsContainerOverflowTest
224 : public BrowserActionsBarRedesignBrowserTest {
225 public:
226 BrowserActionsContainerOverflowTest() : main_bar_(nullptr),
227 overflow_bar_(nullptr) {
229 ~BrowserActionsContainerOverflowTest() override {}
231 protected:
232 // Returns true if the order of the ToolbarActionViews in |main_bar_|
233 // and |overflow_bar_| match.
234 bool ViewOrdersMatch();
236 // Returns Success if the visible count matches |expected_visible|. This means
237 // that the number of visible browser actions in |main_bar_| is
238 // |expected_visible| and shows the first icons, and that the overflow bar
239 // shows all (and only) the remainder.
240 testing::AssertionResult VerifyVisibleCount(size_t expected_visible)
241 WARN_UNUSED_RESULT;
243 // Accessors.
244 BrowserActionsContainer* main_bar() { return main_bar_; }
245 BrowserActionsContainer* overflow_bar() { return overflow_bar_; }
247 private:
248 void SetUpOnMainThread() override;
249 void TearDownOnMainThread() override;
251 // The main BrowserActionsContainer (owned by the browser view).
252 BrowserActionsContainer* main_bar_;
254 // A parent view for the overflow menu.
255 scoped_ptr<views::View> overflow_parent_;
257 // The overflow BrowserActionsContainer. We manufacture this so that we don't
258 // have to open the wrench menu.
259 // Owned by the |overflow_parent_|.
260 BrowserActionsContainer* overflow_bar_;
262 // The associated toolbar model.
263 extensions::ExtensionToolbarModel* model_;
265 DISALLOW_COPY_AND_ASSIGN(BrowserActionsContainerOverflowTest);
268 void BrowserActionsContainerOverflowTest::SetUpOnMainThread() {
269 BrowserActionsBarBrowserTest::SetUpOnMainThread();
270 main_bar_ = BrowserView::GetBrowserViewForBrowser(browser())
271 ->toolbar()->browser_actions();
272 overflow_parent_.reset(new views::View());
273 overflow_parent_->set_owned_by_client();
274 overflow_bar_ = new BrowserActionsContainer(browser(), main_bar_);
275 overflow_parent_->AddChildView(overflow_bar_);
278 void BrowserActionsContainerOverflowTest::TearDownOnMainThread() {
279 overflow_parent_.reset();
280 BrowserActionsBarBrowserTest::TearDownOnMainThread();
283 bool BrowserActionsContainerOverflowTest::ViewOrdersMatch() {
284 if (main_bar_->num_toolbar_actions() !=
285 overflow_bar_->num_toolbar_actions())
286 return false;
287 for (size_t i = 0; i < main_bar_->num_toolbar_actions(); ++i) {
288 if (main_bar_->GetIdAt(i) != overflow_bar_->GetIdAt(i))
289 return false;
291 return true;
294 testing::AssertionResult
295 BrowserActionsContainerOverflowTest::VerifyVisibleCount(
296 size_t expected_visible) {
297 // Views order should always match (as it is based directly off the model).
298 if (!ViewOrdersMatch())
299 return testing::AssertionFailure() << "View orders don't match";
301 // Loop through and check each browser action for proper visibility (which
302 // implicitly also guarantees that the proper number are visible).
303 for (size_t i = 0; i < overflow_bar_->num_toolbar_actions(); ++i) {
304 bool visible = i < expected_visible;
305 if (main_bar_->GetToolbarActionViewAt(i)->visible() != visible) {
306 return testing::AssertionFailure() << "Index " << i <<
307 " has improper visibility in main: " << !visible;
309 if (overflow_bar_->GetToolbarActionViewAt(i)->visible() == visible) {
310 return testing::AssertionFailure() << "Index " << i <<
311 " has improper visibility in overflow: " << visible;
314 return testing::AssertionSuccess();
317 // Test the basic functionality of the BrowserActionsContainer in overflow mode.
318 IN_PROC_BROWSER_TEST_F(BrowserActionsContainerOverflowTest,
319 TestBasicActionOverflow) {
320 LoadExtensions();
322 // Since the overflow bar isn't attached to a view, we have to kick it in
323 // order to retrigger layout each time we change the number of icons in the
324 // bar.
325 overflow_bar()->Layout();
327 // All actions are showing, and are in the installation order.
328 EXPECT_TRUE(toolbar_model()->all_icons_visible());
329 EXPECT_EQ(3u, toolbar_model()->visible_icon_count());
330 ASSERT_EQ(3u, main_bar()->num_toolbar_actions());
331 EXPECT_EQ(extension_a()->id(), main_bar()->GetIdAt(0u));
332 EXPECT_EQ(extension_b()->id(), main_bar()->GetIdAt(1u));
333 EXPECT_EQ(extension_c()->id(), main_bar()->GetIdAt(2u));
334 EXPECT_TRUE(VerifyVisibleCount(3u));
336 // Reduce the visible count to 2. Order should be unchanged (A B C), but
337 // only A and B should be visible on the main bar.
338 toolbar_model()->SetVisibleIconCount(2u);
339 overflow_bar()->Layout(); // Kick.
340 EXPECT_EQ(extension_a()->id(), main_bar()->GetIdAt(0u));
341 EXPECT_EQ(extension_b()->id(), main_bar()->GetIdAt(1u));
342 EXPECT_EQ(extension_c()->id(), main_bar()->GetIdAt(2u));
343 EXPECT_TRUE(VerifyVisibleCount(2u));
345 // Move extension C to the first position. Order should now be C A B, with
346 // C and A visible in the main bar.
347 toolbar_model()->MoveExtensionIcon(extension_c()->id(), 0);
348 overflow_bar()->Layout(); // Kick.
349 EXPECT_EQ(extension_c()->id(), main_bar()->GetIdAt(0u));
350 EXPECT_EQ(extension_a()->id(), main_bar()->GetIdAt(1u));
351 EXPECT_EQ(extension_b()->id(), main_bar()->GetIdAt(2u));
352 EXPECT_TRUE(VerifyVisibleCount(2u));
354 // Hide action A. This results in it being sent to overflow, and reducing the
355 // visible size to 1, so the order should be C A B, with only C visible in the
356 // main bar.
357 extensions::ExtensionActionAPI::SetBrowserActionVisibility(
358 extensions::ExtensionPrefs::Get(profile()),
359 extension_a()->id(),
360 false);
361 overflow_bar()->Layout(); // Kick.
362 EXPECT_EQ(extension_c()->id(), main_bar()->GetIdAt(0u));
363 EXPECT_EQ(extension_a()->id(), main_bar()->GetIdAt(1u));
364 EXPECT_EQ(extension_b()->id(), main_bar()->GetIdAt(2u));
365 EXPECT_TRUE(VerifyVisibleCount(1u));
368 // Test drag and drop between the overflow container and the main container.
369 IN_PROC_BROWSER_TEST_F(BrowserActionsContainerOverflowTest,
370 TestOverflowDragging) {
371 LoadExtensions();
373 // Start with one extension in overflow.
374 toolbar_model()->SetVisibleIconCount(2u);
375 overflow_bar()->Layout();
377 // Verify starting state is A B [C].
378 ASSERT_EQ(3u, main_bar()->num_toolbar_actions());
379 EXPECT_EQ(extension_a()->id(), main_bar()->GetIdAt(0u));
380 EXPECT_EQ(extension_b()->id(), main_bar()->GetIdAt(1u));
381 EXPECT_EQ(extension_c()->id(), main_bar()->GetIdAt(2u));
382 EXPECT_TRUE(VerifyVisibleCount(2u));
384 // Drag extension A (on the main bar) to the left of extension C (in
385 // overflow).
386 ui::OSExchangeData drop_data;
387 BrowserActionDragData browser_action_drag_data(extension_a()->id(), 0u);
388 browser_action_drag_data.Write(profile(), &drop_data);
389 ToolbarActionView* view = overflow_bar()->GetViewForId(extension_c()->id());
390 gfx::Point location(view->x(), view->y());
391 ui::DropTargetEvent target_event(
392 drop_data, location, location, ui::DragDropTypes::DRAG_MOVE);
394 overflow_bar()->OnDragUpdated(target_event);
395 overflow_bar()->OnPerformDrop(target_event);
396 overflow_bar()->Layout();
398 // Order should now be B [A C].
399 EXPECT_EQ(extension_b()->id(), main_bar()->GetIdAt(0u));
400 EXPECT_EQ(extension_a()->id(), main_bar()->GetIdAt(1u));
401 EXPECT_EQ(extension_c()->id(), main_bar()->GetIdAt(2u));
402 EXPECT_TRUE(VerifyVisibleCount(1u));
404 // Drag extension A back from overflow to the main bar.
405 ui::OSExchangeData drop_data2;
406 BrowserActionDragData browser_action_drag_data2(extension_a()->id(), 1u);
407 browser_action_drag_data2.Write(profile(), &drop_data2);
408 view = main_bar()->GetViewForId(extension_b()->id());
409 location = gfx::Point(view->x(), view->y());
410 ui::DropTargetEvent target_event2(
411 drop_data2, location, location, ui::DragDropTypes::DRAG_MOVE);
413 main_bar()->OnDragUpdated(target_event2);
414 main_bar()->OnPerformDrop(target_event2);
416 // Order should be A B [C] again.
417 EXPECT_EQ(extension_a()->id(), main_bar()->GetIdAt(0u));
418 EXPECT_EQ(extension_b()->id(), main_bar()->GetIdAt(1u));
419 EXPECT_EQ(extension_c()->id(), main_bar()->GetIdAt(2u));
420 EXPECT_TRUE(VerifyVisibleCount(2u));
422 // Drag extension C from overflow to the main bar (before extension B).
423 ui::OSExchangeData drop_data3;
424 BrowserActionDragData browser_action_drag_data3(extension_c()->id(), 2u);
425 browser_action_drag_data3.Write(profile(), &drop_data3);
426 location = gfx::Point(view->x(), view->y());
427 ui::DropTargetEvent target_event3(
428 drop_data3, location, location, ui::DragDropTypes::DRAG_MOVE);
430 main_bar()->OnDragUpdated(target_event3);
431 main_bar()->OnPerformDrop(target_event3);
433 // Order should be A C B, and there should be no extensions in overflow.
434 EXPECT_EQ(extension_a()->id(), main_bar()->GetIdAt(0u));
435 EXPECT_EQ(extension_c()->id(), main_bar()->GetIdAt(1u));
436 EXPECT_EQ(extension_b()->id(), main_bar()->GetIdAt(2u));
437 EXPECT_TRUE(VerifyVisibleCount(3u));