Update path of checkdeps to buildtools checkout
[chromium-blink-merge.git] / ui / app_list / views / apps_grid_view_unittest.cc
blobd93943d9c6270f775407df0ce4a8a8c6e0eebb4c
1 // Copyright (c) 2012 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 "ui/app_list/views/apps_grid_view.h"
7 #include <string>
9 #include "base/basictypes.h"
10 #include "base/command_line.h"
11 #include "base/compiler_specific.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/message_loop/message_loop.h"
14 #include "base/strings/utf_string_conversions.h"
15 #include "base/timer/timer.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17 #include "ui/app_list/app_list_constants.h"
18 #include "ui/app_list/app_list_folder_item.h"
19 #include "ui/app_list/app_list_item.h"
20 #include "ui/app_list/app_list_model.h"
21 #include "ui/app_list/app_list_switches.h"
22 #include "ui/app_list/pagination_model.h"
23 #include "ui/app_list/test/app_list_test_model.h"
24 #include "ui/app_list/views/app_list_item_view.h"
25 #include "ui/app_list/views/apps_grid_view_folder_delegate.h"
26 #include "ui/app_list/views/test/apps_grid_view_test_api.h"
27 #include "ui/views/test/views_test_base.h"
29 namespace app_list {
30 namespace test {
32 namespace {
34 const int kIconDimension = 48;
35 const int kCols = 2;
36 const int kRows = 2;
37 const int kTilesPerPage = kCols * kRows;
39 const int kWidth = 320;
40 const int kHeight = 240;
42 class PageFlipWaiter : public PaginationModelObserver {
43 public:
44 PageFlipWaiter(base::MessageLoopForUI* ui_loop, PaginationModel* model)
45 : ui_loop_(ui_loop), model_(model), wait_(false), page_changed_(false) {
46 model_->AddObserver(this);
49 virtual ~PageFlipWaiter() {
50 model_->RemoveObserver(this);
53 bool Wait(int time_out_ms) {
54 DCHECK(!wait_);
55 wait_ = true;
56 page_changed_ = false;
58 if (time_out_ms) {
59 wait_timer_.Stop();
60 wait_timer_.Start(FROM_HERE,
61 base::TimeDelta::FromMilliseconds(time_out_ms),
62 this, &PageFlipWaiter::OnWaitTimeOut);
65 ui_loop_->Run();
66 wait_ = false;
67 return page_changed_;
70 private:
71 void OnWaitTimeOut() {
72 ui_loop_->Quit();
75 // PaginationModelObserver overrides:
76 virtual void TotalPagesChanged() OVERRIDE {
78 virtual void SelectedPageChanged(int old_selected,
79 int new_selected) OVERRIDE {
80 page_changed_ = true;
81 if (wait_)
82 ui_loop_->Quit();
84 virtual void TransitionStarted() OVERRIDE {
86 virtual void TransitionChanged() OVERRIDE {
89 base::MessageLoopForUI* ui_loop_;
90 PaginationModel* model_;
91 bool wait_;
92 bool page_changed_;
93 base::OneShotTimer<PageFlipWaiter> wait_timer_;
95 DISALLOW_COPY_AND_ASSIGN(PageFlipWaiter);
98 } // namespace
100 class AppsGridViewTest : public views::ViewsTestBase {
101 public:
102 AppsGridViewTest() {}
103 virtual ~AppsGridViewTest() {}
105 // testing::Test overrides:
106 virtual void SetUp() OVERRIDE {
107 views::ViewsTestBase::SetUp();
108 model_.reset(new AppListTestModel);
109 pagination_model_.reset(new PaginationModel);
111 apps_grid_view_.reset(new AppsGridView(NULL, pagination_model_.get()));
112 apps_grid_view_->SetLayout(kIconDimension, kCols, kRows);
113 apps_grid_view_->SetBoundsRect(gfx::Rect(gfx::Size(kWidth, kHeight)));
114 apps_grid_view_->SetModel(model_.get());
115 apps_grid_view_->SetItemList(model_->top_level_item_list());
117 test_api_.reset(new AppsGridViewTestApi(apps_grid_view_.get()));
119 virtual void TearDown() OVERRIDE {
120 apps_grid_view_.reset(); // Release apps grid view before models.
121 views::ViewsTestBase::TearDown();
124 protected:
125 void EnsureFoldersEnabled() {
126 // Folders require AppList sync to be enabled.
127 CommandLine::ForCurrentProcess()->AppendSwitch(
128 switches::kEnableSyncAppList);
131 AppListItemView* GetItemViewAt(int index) {
132 return static_cast<AppListItemView*>(
133 test_api_->GetViewAtModelIndex(index));
136 AppListItemView* GetItemViewForPoint(const gfx::Point& point) {
137 for (size_t i = 0; i < model_->top_level_item_list()->item_count(); ++i) {
138 AppListItemView* view = GetItemViewAt(i);
139 if (view->bounds().Contains(point))
140 return view;
142 return NULL;
145 gfx::Rect GetItemTileRectAt(int row, int col) {
146 DCHECK_GT(model_->top_level_item_list()->item_count(), 0u);
148 gfx::Insets insets(apps_grid_view_->GetInsets());
149 gfx::Rect rect(gfx::Point(insets.left(), insets.top()),
150 GetItemViewAt(0)->bounds().size());
151 rect.Offset(col * rect.width(), row * rect.height());
152 return rect;
155 // Points are in |apps_grid_view_|'s coordinates.
156 void SimulateDrag(AppsGridView::Pointer pointer,
157 const gfx::Point& from,
158 const gfx::Point& to) {
159 AppListItemView* view = GetItemViewForPoint(from);
160 DCHECK(view);
162 gfx::Point translated_from = gfx::PointAtOffsetFromOrigin(
163 from - view->bounds().origin());
164 gfx::Point translated_to = gfx::PointAtOffsetFromOrigin(
165 to - view->bounds().origin());
167 ui::MouseEvent pressed_event(ui::ET_MOUSE_PRESSED,
168 translated_from, from, 0, 0);
169 apps_grid_view_->InitiateDrag(view, pointer, pressed_event);
171 ui::MouseEvent drag_event(ui::ET_MOUSE_DRAGGED,
172 translated_to, to, 0, 0);
173 apps_grid_view_->UpdateDragFromItem(pointer, drag_event);
176 void SimulateKeyPress(ui::KeyboardCode key_code) {
177 ui::KeyEvent key_event(ui::ET_KEY_PRESSED, key_code, 0, false);
178 apps_grid_view_->OnKeyPressed(key_event);
181 scoped_ptr<AppListTestModel> model_;
182 scoped_ptr<PaginationModel> pagination_model_;
183 scoped_ptr<AppsGridView> apps_grid_view_;
184 scoped_ptr<AppsGridViewTestApi> test_api_;
186 private:
187 DISALLOW_COPY_AND_ASSIGN(AppsGridViewTest);
190 class TestAppsGridViewFolderDelegate : public AppsGridViewFolderDelegate {
191 public:
192 TestAppsGridViewFolderDelegate() : show_bubble_(false) {}
193 virtual ~TestAppsGridViewFolderDelegate() {}
195 // Overridden from AppsGridViewFolderDelegate:
196 virtual void UpdateFolderViewBackground(bool show_bubble) OVERRIDE {
197 show_bubble_ = show_bubble;
200 virtual void ReparentItem(AppListItemView* original_drag_view,
201 const gfx::Point& drag_point_in_folder_grid)
202 OVERRIDE {}
204 virtual void DispatchDragEventForReparent(
205 AppsGridView::Pointer pointer,
206 const gfx::Point& drag_point_in_folder_grid) OVERRIDE {}
208 virtual void DispatchEndDragEventForReparent(
209 bool events_forwarded_to_drag_drop_host,
210 bool cancel_drag) OVERRIDE {}
212 virtual bool IsPointOutsideOfFolderBoundary(const gfx::Point& point)
213 OVERRIDE {
214 return false;
217 virtual bool IsOEMFolder() const OVERRIDE { return false; }
219 virtual void SetRootLevelDragViewVisible(bool visible) OVERRIDE {}
221 bool show_bubble() { return show_bubble_; }
223 private:
224 bool show_bubble_;
226 DISALLOW_COPY_AND_ASSIGN(TestAppsGridViewFolderDelegate);
229 TEST_F(AppsGridViewTest, CreatePage) {
230 // Fully populates a page.
231 const int kPages = 1;
232 model_->PopulateApps(kPages * kTilesPerPage);
233 EXPECT_EQ(kPages, pagination_model_->total_pages());
235 // Adds one more and gets a new page created.
236 model_->CreateAndAddItem("Extra");
237 EXPECT_EQ(kPages + 1, pagination_model_->total_pages());
240 TEST_F(AppsGridViewTest, EnsureHighlightedVisible) {
241 const int kPages = 3;
242 model_->PopulateApps(kPages * kTilesPerPage);
243 EXPECT_EQ(kPages, pagination_model_->total_pages());
244 EXPECT_EQ(0, pagination_model_->selected_page());
246 // Highlight first one and last one one first page and first page should be
247 // selected.
248 model_->HighlightItemAt(0);
249 EXPECT_EQ(0, pagination_model_->selected_page());
250 model_->HighlightItemAt(kTilesPerPage - 1);
251 EXPECT_EQ(0, pagination_model_->selected_page());
253 // Highlight first one on 2nd page and 2nd page should be selected.
254 model_->HighlightItemAt(kTilesPerPage + 1);
255 EXPECT_EQ(1, pagination_model_->selected_page());
257 // Highlight last one in the model and last page should be selected.
258 model_->HighlightItemAt(model_->top_level_item_list()->item_count() - 1);
259 EXPECT_EQ(kPages - 1, pagination_model_->selected_page());
262 TEST_F(AppsGridViewTest, RemoveSelectedLastApp) {
263 const int kTotalItems = 2;
264 const int kLastItemIndex = kTotalItems - 1;
266 model_->PopulateApps(kTotalItems);
268 AppListItemView* last_view = GetItemViewAt(kLastItemIndex);
269 apps_grid_view_->SetSelectedView(last_view);
270 model_->DeleteItem(model_->GetItemName(kLastItemIndex));
272 EXPECT_FALSE(apps_grid_view_->IsSelectedView(last_view));
274 // No crash happens.
275 AppListItemView* view = GetItemViewAt(0);
276 apps_grid_view_->SetSelectedView(view);
277 EXPECT_TRUE(apps_grid_view_->IsSelectedView(view));
280 TEST_F(AppsGridViewTest, MouseDragWithFolderDisabled) {
281 CommandLine::ForCurrentProcess()->AppendSwitch(switches::kDisableSyncAppList);
282 const int kTotalItems = 4;
283 model_->PopulateApps(kTotalItems);
284 EXPECT_EQ(std::string("Item 0,Item 1,Item 2,Item 3"),
285 model_->GetModelContent());
287 gfx::Point from = GetItemTileRectAt(0, 0).CenterPoint();
288 gfx::Point to = GetItemTileRectAt(0, 1).CenterPoint();
290 // Dragging changes model order.
291 SimulateDrag(AppsGridView::MOUSE, from, to);
292 apps_grid_view_->EndDrag(false);
293 EXPECT_EQ(std::string("Item 1,Item 0,Item 2,Item 3"),
294 model_->GetModelContent());
295 test_api_->LayoutToIdealBounds();
297 // Canceling drag should keep existing order.
298 SimulateDrag(AppsGridView::MOUSE, from, to);
299 apps_grid_view_->EndDrag(true);
300 EXPECT_EQ(std::string("Item 1,Item 0,Item 2,Item 3"),
301 model_->GetModelContent());
302 test_api_->LayoutToIdealBounds();
304 // Deleting an item keeps remaining intact.
305 SimulateDrag(AppsGridView::MOUSE, from, to);
306 model_->DeleteItem(model_->GetItemName(0));
307 apps_grid_view_->EndDrag(false);
308 EXPECT_EQ(std::string("Item 1,Item 2,Item 3"),
309 model_->GetModelContent());
310 test_api_->LayoutToIdealBounds();
312 // Adding a launcher item cancels the drag and respects the order.
313 SimulateDrag(AppsGridView::MOUSE, from, to);
314 model_->CreateAndAddItem("Extra");
315 apps_grid_view_->EndDrag(false);
316 EXPECT_EQ(std::string("Item 1,Item 2,Item 3,Extra"),
317 model_->GetModelContent());
318 test_api_->LayoutToIdealBounds();
321 TEST_F(AppsGridViewTest, MouseDragItemIntoFolder) {
322 EnsureFoldersEnabled();
324 size_t kTotalItems = 3;
325 model_->PopulateApps(kTotalItems);
326 EXPECT_EQ(model_->top_level_item_list()->item_count(), kTotalItems);
327 EXPECT_EQ(std::string("Item 0,Item 1,Item 2"), model_->GetModelContent());
329 gfx::Point from = GetItemTileRectAt(0, 1).CenterPoint();
330 gfx::Point to = GetItemTileRectAt(0, 0).CenterPoint();
332 // Dragging item_1 over item_0 creates a folder.
333 SimulateDrag(AppsGridView::MOUSE, from, to);
334 apps_grid_view_->EndDrag(false);
335 EXPECT_EQ(kTotalItems - 1, model_->top_level_item_list()->item_count());
336 EXPECT_EQ(AppListFolderItem::kItemType,
337 model_->top_level_item_list()->item_at(0)->GetItemType());
338 AppListFolderItem* folder_item = static_cast<AppListFolderItem*>(
339 model_->top_level_item_list()->item_at(0));
340 EXPECT_EQ(2u, folder_item->ChildItemCount());
341 AppListItem* item_0 = model_->FindItem("Item 0");
342 EXPECT_TRUE(item_0->IsInFolder());
343 EXPECT_EQ(folder_item->id(), item_0->folder_id());
344 AppListItem* item_1 = model_->FindItem("Item 1");
345 EXPECT_TRUE(item_1->IsInFolder());
346 EXPECT_EQ(folder_item->id(), item_1->folder_id());
347 std::string expected_items = folder_item->id() + ",Item 2";
348 EXPECT_EQ(expected_items, model_->GetModelContent());
349 test_api_->LayoutToIdealBounds();
351 // Dragging item_2 to the folder adds item_2 to the folder.
352 SimulateDrag(AppsGridView::MOUSE, from, to);
353 apps_grid_view_->EndDrag(false);
355 EXPECT_EQ(kTotalItems - 2, model_->top_level_item_list()->item_count());
356 EXPECT_EQ(folder_item->id(), model_->GetModelContent());
357 EXPECT_EQ(3u, folder_item->ChildItemCount());
358 item_0 = model_->FindItem("Item 0");
359 EXPECT_TRUE(item_0->IsInFolder());
360 EXPECT_EQ(folder_item->id(), item_0->folder_id());
361 item_1 = model_->FindItem("Item 1");
362 EXPECT_TRUE(item_1->IsInFolder());
363 EXPECT_EQ(folder_item->id(), item_1->folder_id());
364 AppListItem* item_2 = model_->FindItem("Item 2");
365 EXPECT_TRUE(item_2->IsInFolder());
366 EXPECT_EQ(folder_item->id(), item_2->folder_id());
367 test_api_->LayoutToIdealBounds();
370 TEST_F(AppsGridViewTest, MouseDragMaxItemsInFolder) {
371 EnsureFoldersEnabled();
373 // Create and add a folder with 15 items in it.
374 size_t kTotalItems = kMaxFolderItems - 1;
375 model_->CreateAndPopulateFolderWithApps(kTotalItems);
376 EXPECT_EQ(1u, model_->top_level_item_list()->item_count());
377 EXPECT_EQ(AppListFolderItem::kItemType,
378 model_->top_level_item_list()->item_at(0)->GetItemType());
379 AppListFolderItem* folder_item = static_cast<AppListFolderItem*>(
380 model_->top_level_item_list()->item_at(0));
381 EXPECT_EQ(kTotalItems, folder_item->ChildItemCount());
383 // Create and add another 2 items.
384 model_->PopulateAppWithId(kTotalItems);
385 model_->PopulateAppWithId(kTotalItems + 1);
386 EXPECT_EQ(3u, model_->top_level_item_list()->item_count());
387 EXPECT_EQ(folder_item->id(), model_->top_level_item_list()->item_at(0)->id());
388 EXPECT_EQ(model_->GetItemName(kMaxFolderItems - 1),
389 model_->top_level_item_list()->item_at(1)->id());
390 EXPECT_EQ(model_->GetItemName(kMaxFolderItems),
391 model_->top_level_item_list()->item_at(2)->id());
393 gfx::Point from = GetItemTileRectAt(0, 1).CenterPoint();
394 gfx::Point to = GetItemTileRectAt(0, 0).CenterPoint();
396 // Dragging one item into the folder, the folder should accept the item.
397 SimulateDrag(AppsGridView::MOUSE, from, to);
398 apps_grid_view_->EndDrag(false);
399 EXPECT_EQ(2u, model_->top_level_item_list()->item_count());
400 EXPECT_EQ(folder_item->id(), model_->top_level_item_list()->item_at(0)->id());
401 EXPECT_EQ(kMaxFolderItems, folder_item->ChildItemCount());
402 EXPECT_EQ(model_->GetItemName(kMaxFolderItems),
403 model_->top_level_item_list()->item_at(1)->id());
404 test_api_->LayoutToIdealBounds();
406 // Dragging the last item over the folder, the folder won't accept the new
407 // item, instead, it will re-order the items.
408 SimulateDrag(AppsGridView::MOUSE, from, to);
409 apps_grid_view_->EndDrag(false);
410 EXPECT_EQ(2u, model_->top_level_item_list()->item_count());
411 EXPECT_EQ(model_->GetItemName(kMaxFolderItems),
412 model_->top_level_item_list()->item_at(0)->id());
413 EXPECT_EQ(folder_item->id(), model_->top_level_item_list()->item_at(1)->id());
414 EXPECT_EQ(kMaxFolderItems, folder_item->ChildItemCount());
415 test_api_->LayoutToIdealBounds();
418 TEST_F(AppsGridViewTest, MouseDragItemReorder) {
419 // This test assumes Folders are enabled.
420 EnsureFoldersEnabled();
422 size_t kTotalItems = 2;
423 model_->PopulateApps(kTotalItems);
424 EXPECT_EQ(2u, model_->top_level_item_list()->item_count());
425 EXPECT_EQ(std::string("Item 0,Item 1"), model_->GetModelContent());
427 gfx::Point from = GetItemTileRectAt(0, 1).CenterPoint();
428 int reorder_offset = (GetItemTileRectAt(0, 1).CenterPoint() -
429 GetItemTileRectAt(0, 0).CenterPoint()).Length() -
430 kReorderDroppingCircleRadius -
431 kPreferredIconDimension / 2 + 5;
432 gfx::Point to = gfx::Point(from.x() - reorder_offset, from.y());
434 // Dragging item_1 closing to item_0 should leads to re-ordering these two
435 // items.
436 SimulateDrag(AppsGridView::MOUSE, from, to);
437 apps_grid_view_->EndDrag(false);
438 EXPECT_EQ(2u, model_->top_level_item_list()->item_count());
439 EXPECT_EQ(std::string("Item 1,Item 0"), model_->GetModelContent());
440 test_api_->LayoutToIdealBounds();
443 TEST_F(AppsGridViewTest, MouseDragFolderReorder) {
444 EnsureFoldersEnabled();
446 size_t kTotalItems = 2;
447 model_->CreateAndPopulateFolderWithApps(kTotalItems);
448 model_->PopulateAppWithId(kTotalItems);
449 EXPECT_EQ(2u, model_->top_level_item_list()->item_count());
450 EXPECT_EQ(AppListFolderItem::kItemType,
451 model_->top_level_item_list()->item_at(0)->GetItemType());
452 AppListFolderItem* folder_item = static_cast<AppListFolderItem*>(
453 model_->top_level_item_list()->item_at(0));
454 EXPECT_EQ("Item 2", model_->top_level_item_list()->item_at(1)->id());
456 gfx::Point from = GetItemTileRectAt(0, 0).CenterPoint();
457 gfx::Point to = GetItemTileRectAt(0, 1).CenterPoint();
459 // Dragging folder over item_1 should leads to re-ordering these two
460 // items.
461 SimulateDrag(AppsGridView::MOUSE, from, to);
462 apps_grid_view_->EndDrag(false);
463 EXPECT_EQ(2u, model_->top_level_item_list()->item_count());
464 EXPECT_EQ("Item 2", model_->top_level_item_list()->item_at(0)->id());
465 EXPECT_EQ(folder_item->id(), model_->top_level_item_list()->item_at(1)->id());
466 test_api_->LayoutToIdealBounds();
469 TEST_F(AppsGridViewTest, MouseDragWithCancelDeleteAddItem) {
470 size_t kTotalItems = 4;
471 model_->PopulateApps(kTotalItems);
472 EXPECT_EQ(model_->top_level_item_list()->item_count(), kTotalItems);
473 EXPECT_EQ(std::string("Item 0,Item 1,Item 2,Item 3"),
474 model_->GetModelContent());
476 gfx::Point from = GetItemTileRectAt(0, 0).CenterPoint();
477 gfx::Point to = GetItemTileRectAt(0, 1).CenterPoint();
479 // Canceling drag should keep existing order.
480 SimulateDrag(AppsGridView::MOUSE, from, to);
481 apps_grid_view_->EndDrag(true);
482 EXPECT_EQ(std::string("Item 0,Item 1,Item 2,Item 3"),
483 model_->GetModelContent());
484 test_api_->LayoutToIdealBounds();
486 // Deleting an item keeps remaining intact.
487 SimulateDrag(AppsGridView::MOUSE, from, to);
488 model_->DeleteItem(model_->GetItemName(2));
489 apps_grid_view_->EndDrag(false);
490 EXPECT_EQ(std::string("Item 0,Item 1,Item 3"), model_->GetModelContent());
491 test_api_->LayoutToIdealBounds();
493 // Adding a launcher item cancels the drag and respects the order.
494 SimulateDrag(AppsGridView::MOUSE, from, to);
495 model_->CreateAndAddItem("Extra");
496 apps_grid_view_->EndDrag(false);
497 EXPECT_EQ(std::string("Item 0,Item 1,Item 3,Extra"),
498 model_->GetModelContent());
499 test_api_->LayoutToIdealBounds();
502 TEST_F(AppsGridViewTest, MouseDragFlipPage) {
503 test_api_->SetPageFlipDelay(10);
504 pagination_model_->SetTransitionDurations(10, 10);
506 PageFlipWaiter page_flip_waiter(message_loop(),
507 pagination_model_.get());
509 const int kPages = 3;
510 model_->PopulateApps(kPages * kTilesPerPage);
511 EXPECT_EQ(kPages, pagination_model_->total_pages());
512 EXPECT_EQ(0, pagination_model_->selected_page());
514 gfx::Point from = GetItemTileRectAt(0, 0).CenterPoint();
515 gfx::Point to = gfx::Point(apps_grid_view_->width(),
516 apps_grid_view_->height() / 2);
518 // Drag to right edge.
519 SimulateDrag(AppsGridView::MOUSE, from, to);
521 // Page should be flipped after sometime.
522 EXPECT_TRUE(page_flip_waiter.Wait(0));
523 EXPECT_EQ(1, pagination_model_->selected_page());
525 // Stay there and page should be flipped again.
526 EXPECT_TRUE(page_flip_waiter.Wait(0));
527 EXPECT_EQ(2, pagination_model_->selected_page());
529 // Stay there longer and no page flip happen since we are at the last page.
530 EXPECT_FALSE(page_flip_waiter.Wait(100));
531 EXPECT_EQ(2, pagination_model_->selected_page());
533 apps_grid_view_->EndDrag(true);
535 // Now drag to the left edge and test the other direction.
536 to.set_x(0);
538 SimulateDrag(AppsGridView::MOUSE, from, to);
540 EXPECT_TRUE(page_flip_waiter.Wait(0));
541 EXPECT_EQ(1, pagination_model_->selected_page());
543 EXPECT_TRUE(page_flip_waiter.Wait(0));
544 EXPECT_EQ(0, pagination_model_->selected_page());
546 EXPECT_FALSE(page_flip_waiter.Wait(100));
547 EXPECT_EQ(0, pagination_model_->selected_page());
548 apps_grid_view_->EndDrag(true);
551 TEST_F(AppsGridViewTest, SimultaneousDragWithFolderDisabled) {
552 CommandLine::ForCurrentProcess()->AppendSwitch(switches::kDisableSyncAppList);
553 const int kTotalItems = 4;
554 model_->PopulateApps(kTotalItems);
555 EXPECT_EQ(std::string("Item 0,Item 1,Item 2,Item 3"),
556 model_->GetModelContent());
558 gfx::Point mouse_from = GetItemTileRectAt(0, 0).CenterPoint();
559 gfx::Point mouse_to = GetItemTileRectAt(0, 1).CenterPoint();
561 gfx::Point touch_from = GetItemTileRectAt(1, 0).CenterPoint();
562 gfx::Point touch_to = GetItemTileRectAt(1, 1).CenterPoint();
564 // Starts a mouse drag first then a touch drag.
565 SimulateDrag(AppsGridView::MOUSE, mouse_from, mouse_to);
566 SimulateDrag(AppsGridView::TOUCH, touch_from, touch_to);
567 // Finishes the drag and mouse drag wins.
568 apps_grid_view_->EndDrag(false);
569 EXPECT_EQ(std::string("Item 1,Item 0,Item 2,Item 3"),
570 model_->GetModelContent());
571 test_api_->LayoutToIdealBounds();
573 // Starts a touch drag first then a mouse drag.
574 SimulateDrag(AppsGridView::TOUCH, touch_from, touch_to);
575 SimulateDrag(AppsGridView::MOUSE, mouse_from, mouse_to);
576 // Finishes the drag and touch drag wins.
577 apps_grid_view_->EndDrag(false);
578 EXPECT_EQ(std::string("Item 1,Item 0,Item 3,Item 2"),
579 model_->GetModelContent());
580 test_api_->LayoutToIdealBounds();
583 TEST_F(AppsGridViewTest, UpdateFolderBackgroundOnCancelDrag) {
584 EnsureFoldersEnabled();
586 const int kTotalItems = 4;
587 TestAppsGridViewFolderDelegate folder_delegate;
588 apps_grid_view_->set_folder_delegate(&folder_delegate);
589 model_->PopulateApps(kTotalItems);
590 EXPECT_EQ(std::string("Item 0,Item 1,Item 2,Item 3"),
591 model_->GetModelContent());
593 gfx::Point mouse_from = GetItemTileRectAt(0, 0).CenterPoint();
594 gfx::Point mouse_to = GetItemTileRectAt(0, 1).CenterPoint();
596 // Starts a mouse drag and then cancels it.
597 SimulateDrag(AppsGridView::MOUSE, mouse_from, mouse_to);
598 EXPECT_TRUE(folder_delegate.show_bubble());
599 apps_grid_view_->EndDrag(true);
600 EXPECT_FALSE(folder_delegate.show_bubble());
601 EXPECT_EQ(std::string("Item 0,Item 1,Item 2,Item 3"),
602 model_->GetModelContent());
605 TEST_F(AppsGridViewTest, HighlightWithKeyboard) {
606 const int kPages = 3;
607 const int kItems = (kPages - 1) * kTilesPerPage + 1;
608 model_->PopulateApps(kItems);
610 const int first_index = 0;
611 const int last_index = kItems - 1;
612 const int last_index_on_page1_first_row = kRows - 1;
613 const int last_index_on_page1 = kTilesPerPage - 1;
614 const int first_index_on_page2 = kTilesPerPage;
615 const int first_index_on_page2_last_row = 2 * kTilesPerPage - kRows;
616 const int last_index_on_page2_last_row = 2 * kTilesPerPage - 1;
618 // Try moving off the item beyond the first one.
619 apps_grid_view_->SetSelectedView(GetItemViewAt(first_index));
620 SimulateKeyPress(ui::VKEY_UP);
621 EXPECT_TRUE(apps_grid_view_->IsSelectedView(GetItemViewAt(first_index)));
622 SimulateKeyPress(ui::VKEY_LEFT);
623 EXPECT_TRUE(apps_grid_view_->IsSelectedView(GetItemViewAt(first_index)));
625 // Move to the last item and try to go past it.
626 apps_grid_view_->SetSelectedView(GetItemViewAt(last_index));
627 SimulateKeyPress(ui::VKEY_DOWN);
628 EXPECT_TRUE(apps_grid_view_->IsSelectedView(GetItemViewAt(last_index)));
629 SimulateKeyPress(ui::VKEY_RIGHT);
630 EXPECT_TRUE(apps_grid_view_->IsSelectedView(GetItemViewAt(last_index)));
632 // Move right on last item on page 1 should get to first item on page 2's last
633 // row and vice versa.
634 apps_grid_view_->SetSelectedView(GetItemViewAt(last_index_on_page1));
635 SimulateKeyPress(ui::VKEY_RIGHT);
636 EXPECT_TRUE(apps_grid_view_->IsSelectedView(GetItemViewAt(
637 first_index_on_page2_last_row)));
638 SimulateKeyPress(ui::VKEY_LEFT);
639 EXPECT_TRUE(apps_grid_view_->IsSelectedView(GetItemViewAt(
640 last_index_on_page1)));
642 // Up/down on page boundary does nothing.
643 apps_grid_view_->SetSelectedView(GetItemViewAt(last_index_on_page1));
644 SimulateKeyPress(ui::VKEY_DOWN);
645 EXPECT_TRUE(apps_grid_view_->IsSelectedView(GetItemViewAt(
646 last_index_on_page1)));
647 apps_grid_view_->SetSelectedView(
648 GetItemViewAt(first_index_on_page2_last_row));
649 apps_grid_view_->
650 SetSelectedView(GetItemViewAt(last_index_on_page1_first_row));
651 SimulateKeyPress(ui::VKEY_UP);
652 EXPECT_TRUE(apps_grid_view_->IsSelectedView(GetItemViewAt(
653 last_index_on_page1_first_row)));
655 // Page up and down should go to the same item on the next and last page.
656 apps_grid_view_->SetSelectedView(GetItemViewAt(first_index_on_page2));
657 SimulateKeyPress(ui::VKEY_PRIOR);
658 EXPECT_TRUE(apps_grid_view_->IsSelectedView(GetItemViewAt(
659 first_index)));
660 SimulateKeyPress(ui::VKEY_NEXT);
661 EXPECT_TRUE(apps_grid_view_->IsSelectedView(GetItemViewAt(
662 first_index_on_page2)));
664 // Moving onto a a page with too few apps to support the expected index snaps
665 // to the last available index.
666 apps_grid_view_->SetSelectedView(GetItemViewAt(last_index_on_page2_last_row));
667 SimulateKeyPress(ui::VKEY_RIGHT);
668 EXPECT_TRUE(apps_grid_view_->IsSelectedView(GetItemViewAt(
669 last_index)));
670 apps_grid_view_->SetSelectedView(GetItemViewAt(last_index_on_page2_last_row));
671 SimulateKeyPress(ui::VKEY_NEXT);
672 EXPECT_TRUE(apps_grid_view_->IsSelectedView(GetItemViewAt(
673 last_index)));
677 // After page switch, arrow keys select first item on current page.
678 apps_grid_view_->SetSelectedView(GetItemViewAt(first_index));
679 pagination_model_->SelectPage(1, false);
680 SimulateKeyPress(ui::VKEY_UP);
681 EXPECT_TRUE(apps_grid_view_->IsSelectedView(GetItemViewAt(
682 first_index_on_page2)));
685 TEST_F(AppsGridViewTest, ItemLabelShortNameOverride) {
686 // If the app's full name and short name differ, the title label's tooltip
687 // should always be the full name of the app.
688 std::string expected_text("xyz");
689 std::string expected_tooltip("tooltip");
690 AppListItem* item = model_->CreateAndAddItem("Item with short name");
691 model_->SetItemNameAndShortName(item, expected_tooltip, expected_text);
693 base::string16 actual_tooltip;
694 AppListItemView* item_view = GetItemViewAt(0);
695 ASSERT_TRUE(item_view);
696 const views::Label* title_label = item_view->title();
697 EXPECT_TRUE(title_label->GetTooltipText(
698 title_label->bounds().CenterPoint(), &actual_tooltip));
699 EXPECT_EQ(expected_tooltip, base::UTF16ToUTF8(actual_tooltip));
700 EXPECT_EQ(expected_text, base::UTF16ToUTF8(title_label->text()));
703 TEST_F(AppsGridViewTest, ItemLabelNoShortName) {
704 // If the app's full name and short name are the same, use the default tooltip
705 // behavior of the label (only show a tooltip if the title is truncated).
706 std::string title("a");
707 AppListItem* item = model_->CreateAndAddItem(title);
708 model_->SetItemNameAndShortName(item, title, "");
710 base::string16 actual_tooltip;
711 AppListItemView* item_view = GetItemViewAt(0);
712 ASSERT_TRUE(item_view);
713 const views::Label* title_label = item_view->title();
714 EXPECT_FALSE(title_label->GetTooltipText(
715 title_label->bounds().CenterPoint(), &actual_tooltip));
716 EXPECT_EQ(title, base::UTF16ToUTF8(title_label->text()));
719 } // namespace test
720 } // namespace app_list