1a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 2a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// found in the LICENSE file. 4a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 5a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "ui/app_list/views/app_list_main_view.h" 6a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 7cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 8cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/run_loop.h" 9cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/time/time.h" 10cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/timer/timer.h" 11a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 12a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "ui/app_list/test/app_list_test_model.h" 13a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "ui/app_list/test/app_list_test_view_delegate.h" 14cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ui/app_list/views/app_list_folder_view.h" 15cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ui/app_list/views/app_list_item_view.h" 16a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "ui/app_list/views/apps_container_view.h" 17a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "ui/app_list/views/apps_grid_view.h" 18a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "ui/app_list/views/contents_view.h" 19cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ui/app_list/views/test/apps_grid_view_test_api.h" 20a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "ui/views/test/views_test_base.h" 21a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "ui/views/view_model.h" 22a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "ui/views/widget/widget.h" 23a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 24a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)namespace app_list { 25a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)namespace test { 26a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 27a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)namespace { 28a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 29a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)const int kInitialItems = 2; 30a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 31cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class GridViewVisibleWaiter { 32cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) public: 33cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) explicit GridViewVisibleWaiter(AppsGridView* grid_view) 34cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) : grid_view_(grid_view) {} 35cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ~GridViewVisibleWaiter() {} 36cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 37cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) void Wait() { 38cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (grid_view_->visible()) 39cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 40cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 41cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) check_timer_.Start(FROM_HERE, 42cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::TimeDelta::FromMilliseconds(50), 43cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind(&GridViewVisibleWaiter::OnTimerCheck, 44cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Unretained(this))); 45cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) run_loop_.reset(new base::RunLoop); 46cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) run_loop_->Run(); 47cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) check_timer_.Stop(); 48cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 49cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 50cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) private: 51cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) void OnTimerCheck() { 52cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (grid_view_->visible()) 53cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) run_loop_->Quit(); 54cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 55cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 56cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) AppsGridView* grid_view_; 57cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_ptr<base::RunLoop> run_loop_; 58cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::RepeatingTimer<GridViewVisibleWaiter> check_timer_; 59cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 60cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(GridViewVisibleWaiter); 61cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 62cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 63a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)class AppListMainViewTest : public views::ViewsTestBase { 64a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) public: 65a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) AppListMainViewTest() 66a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) : widget_(NULL), 67a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) main_view_(NULL) {} 68a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 69a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) virtual ~AppListMainViewTest() {} 70a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 71a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // testing::Test overrides: 72a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) virtual void SetUp() OVERRIDE { 73a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) views::ViewsTestBase::SetUp(); 74a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) delegate_.reset(new AppListTestViewDelegate); 75a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // In Ash, the third argument is a container aura::Window, but it is always 775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // NULL on Windows, and not needed for tests. It is only used to determine 785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // the scale factor for preloading icons. 795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) main_view_ = new AppListMainView(delegate_.get(), 0, NULL); 80a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) main_view_->SetPaintToLayer(true); 8146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) main_view_->model()->SetFoldersEnabled(true); 82a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 83a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) widget_ = new views::Widget; 84a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) views::Widget::InitParams params = 85a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) CreateParams(views::Widget::InitParams::TYPE_POPUP); 86a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) params.bounds.set_size(main_view_->GetPreferredSize()); 87a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) widget_->Init(params); 88a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 89a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) widget_->SetContentsView(main_view_); 90a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 91a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 92a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) virtual void TearDown() OVERRIDE { 93a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) widget_->Close(); 94a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) views::ViewsTestBase::TearDown(); 95a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) delegate_.reset(); 96a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 97a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 98cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // |point| is in |grid_view|'s coordinates. 99cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) AppListItemView* GetItemViewAtPointInGrid(AppsGridView* grid_view, 100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const gfx::Point& point) { 101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const views::ViewModel* view_model = grid_view->view_model_for_test(); 102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) for (int i = 0; i < view_model->view_size(); ++i) { 103cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) views::View* view = view_model->view_at(i); 104cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (view->bounds().Contains(point)) { 105cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return static_cast<AppListItemView*>(view); 106cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return NULL; 110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) void SimulateClick(views::View* view) { 113cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) gfx::Point center = view->GetLocalBounds().CenterPoint(); 114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) view->OnMousePressed(ui::MouseEvent(ui::ET_MOUSE_PRESSED, 115cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) center, 116cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) center, 117cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ui::EF_LEFT_MOUSE_BUTTON, 118cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ui::EF_LEFT_MOUSE_BUTTON)); 119cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) view->OnMouseReleased(ui::MouseEvent(ui::ET_MOUSE_RELEASED, 120cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) center, 121cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) center, 122cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ui::EF_LEFT_MOUSE_BUTTON, 123cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ui::EF_LEFT_MOUSE_BUTTON)); 124cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 125cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 126cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // |point| is in |grid_view|'s coordinates. 127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) AppListItemView* SimulateInitiateDrag(AppsGridView* grid_view, 128cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) AppsGridView::Pointer pointer, 129cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const gfx::Point& point) { 130cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) AppListItemView* view = GetItemViewAtPointInGrid(grid_view, point); 131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK(view); 132cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) gfx::Point translated = 134cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) gfx::PointAtOffsetFromOrigin(point - view->bounds().origin()); 135cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ui::MouseEvent pressed_event(ui::ET_MOUSE_PRESSED, translated, point, 0, 0); 136cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) grid_view->InitiateDrag(view, pointer, pressed_event); 137cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return view; 138cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 139cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 140cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // |point| is in |grid_view|'s coordinates. 141cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) void SimulateUpdateDrag(AppsGridView* grid_view, 142cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) AppsGridView::Pointer pointer, 143cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) AppListItemView* drag_view, 144cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const gfx::Point& point) { 145cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK(drag_view); 146cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) gfx::Point translated = 147cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) gfx::PointAtOffsetFromOrigin(point - drag_view->bounds().origin()); 148cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ui::MouseEvent drag_event(ui::ET_MOUSE_DRAGGED, translated, point, 0, 0); 149cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) grid_view->UpdateDragFromItem(pointer, drag_event); 150cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 151cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 152cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) AppsGridView* RootGridView() { 153cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return main_view_->contents_view()->apps_container_view()->apps_grid_view(); 154cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 155cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 156cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) AppListFolderView* FolderView() { 157cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return main_view_->contents_view() 158cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ->apps_container_view() 159cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ->app_list_folder_view(); 160cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 161cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 162cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) AppsGridView* FolderGridView() { return FolderView()->items_grid_view(); } 163cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 164cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const views::ViewModel* RootViewModel() { 165cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return RootGridView()->view_model_for_test(); 166cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 167cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 168cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const views::ViewModel* FolderViewModel() { 169cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return FolderGridView()->view_model_for_test(); 170a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 171a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 1726e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) AppListItemView* CreateAndOpenSingleItemFolder() { 1736e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // Prepare single folder with a single item in it. 1746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) AppListFolderItem* folder_item = 1756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) delegate_->GetTestModel()->CreateSingleItemFolder("single_item_folder", 1766e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) "single"); 1776e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) EXPECT_EQ(folder_item, 1786e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) delegate_->GetTestModel()->FindFolderItem("single_item_folder")); 1796e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) EXPECT_EQ(AppListFolderItem::kItemType, folder_item->GetItemType()); 1806e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1816e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) EXPECT_EQ(1, RootViewModel()->view_size()); 1826e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) AppListItemView* folder_item_view = 1836e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) static_cast<AppListItemView*>(RootViewModel()->view_at(0)); 1846e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) EXPECT_EQ(folder_item_view->item(), folder_item); 1856e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1866e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // Click on the folder to open it. 1876e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) EXPECT_FALSE(FolderView()->visible()); 1886e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) SimulateClick(folder_item_view); 1896e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) base::RunLoop().RunUntilIdle(); 1906e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) EXPECT_TRUE(FolderView()->visible()); 1916e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1926e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#if defined(OS_WIN) 1936e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) AppsGridViewTestApi folder_grid_view_test_api(FolderGridView()); 1946e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) folder_grid_view_test_api.DisableSynchronousDrag(); 1956e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#endif 1966e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return folder_item_view; 1976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 1986e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1996e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) AppListItemView* StartDragForReparent(int index_in_folder) { 2006e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // Start to drag the item in folder. 2016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) views::View* item_view = FolderViewModel()->view_at(index_in_folder); 2026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) gfx::Point point = item_view->bounds().CenterPoint(); 2036e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) AppListItemView* dragged = 2046e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) SimulateInitiateDrag(FolderGridView(), AppsGridView::MOUSE, point); 2056e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) EXPECT_EQ(item_view, dragged); 2066e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) EXPECT_FALSE(RootGridView()->visible()); 2076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) EXPECT_TRUE(FolderView()->visible()); 2086e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 2096e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // Drag it to top left corner. 2106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) point = gfx::Point(0, 0); 2116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // Two update drags needed to actually drag the view. The first changes 2126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // state and the 2nd one actually moves the view. The 2nd call can be 2136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // removed when UpdateDrag is fixed. 2146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) SimulateUpdateDrag(FolderGridView(), AppsGridView::MOUSE, dragged, point); 2156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) SimulateUpdateDrag(FolderGridView(), AppsGridView::MOUSE, dragged, point); 2166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) base::RunLoop().RunUntilIdle(); 2176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 2186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // Wait until the folder view is invisible and root grid view shows up. 2196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) GridViewVisibleWaiter(RootGridView()).Wait(); 2206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) EXPECT_TRUE(RootGridView()->visible()); 2216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) EXPECT_EQ(0, FolderView()->layer()->opacity()); 2226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 2236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return dragged; 2246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 2256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 226a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) protected: 227a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) views::Widget* widget_; // Owned by native window. 228a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) AppListMainView* main_view_; // Owned by |widget_|. 229a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_ptr<AppListTestViewDelegate> delegate_; 230a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 231a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) private: 232a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(AppListMainViewTest); 233a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}; 234a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 235a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} // namespace 236a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 237a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Tests changing the AppListModel when switching profiles. 238a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_F(AppListMainViewTest, ModelChanged) { 239cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) delegate_->GetTestModel()->PopulateApps(kInitialItems); 240cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_EQ(kInitialItems, RootViewModel()->view_size()); 241a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 242a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // The model is owned by a profile keyed service, which is never destroyed 243a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // until after profile switching. 244a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_ptr<AppListModel> old_model(delegate_->ReleaseTestModel()); 245a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 246a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const int kReplacementItems = 5; 247a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) delegate_->ReplaceTestModel(kReplacementItems); 248a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) main_view_->ModelChanged(); 249cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_EQ(kReplacementItems, RootViewModel()->view_size()); 250cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 251cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 252cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Tests dragging an item out of a single item folder and drop it at the last 253cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// slot. 254cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TEST_F(AppListMainViewTest, DragLastItemFromFolderAndDropAtLastSlot) { 2556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) AppListItemView* folder_item_view = CreateAndOpenSingleItemFolder(); 256cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const gfx::Rect first_slot_tile = folder_item_view->bounds(); 257cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 258cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_EQ(1, FolderViewModel()->view_size()); 259cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 2606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) AppListItemView* dragged = StartDragForReparent(0); 261cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 262cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Drop it to the slot on the right of first slot. 263cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) gfx::Rect drop_target_tile(first_slot_tile); 2641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci drop_target_tile.Offset(first_slot_tile.width() * 2, 0); 2656e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) gfx::Point point = drop_target_tile.CenterPoint(); 266cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) SimulateUpdateDrag(FolderGridView(), AppsGridView::MOUSE, dragged, point); 267cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 268cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Drop it. 269cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) FolderGridView()->EndDrag(false); 270cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 271cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Folder icon view should be gone and there is only one item view. 272cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_EQ(1, RootViewModel()->view_size()); 273cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_EQ(AppListItemView::kViewClassName, 274cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) RootViewModel()->view_at(0)->GetClassName()); 275cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 276cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // The item view should be in slot 1 instead of slot 2 where it is dropped. 277cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) AppsGridViewTestApi root_grid_view_test_api(RootGridView()); 278cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) root_grid_view_test_api.LayoutToIdealBounds(); 279cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_EQ(first_slot_tile, RootViewModel()->view_at(0)->bounds()); 280cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 281cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Single item folder should be auto removed. 282cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_EQ(NULL, 283cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) delegate_->GetTestModel()->FindFolderItem("single_item_folder")); 284a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 285a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 2861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Tests dragging an item out of a single item folder and dropping it onto the 2871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// page switcher. Regression test for http://crbug.com/415530/. 2881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_F(AppListMainViewTest, DragReparentItemOntoPageSwitcher) { 2891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci AppListItemView* folder_item_view = CreateAndOpenSingleItemFolder(); 2901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const gfx::Rect first_slot_tile = folder_item_view->bounds(); 2911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci delegate_->GetTestModel()->PopulateApps(20); 2931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_EQ(1, FolderViewModel()->view_size()); 2951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_EQ(21, RootViewModel()->view_size()); 2961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci AppListItemView* dragged = StartDragForReparent(0); 2981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci gfx::Rect main_view_bounds = main_view_->bounds(); 3001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Drag the reparent item to the page switcher. 3011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci gfx::Point point = 3021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci gfx::Point(main_view_bounds.width() / 2, 3031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci main_view_bounds.bottom() - first_slot_tile.height()); 3041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci SimulateUpdateDrag(FolderGridView(), AppsGridView::MOUSE, dragged, point); 3051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Drop it. 3071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci FolderGridView()->EndDrag(false); 3081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // The folder should be destroyed. 3101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_EQ(21, RootViewModel()->view_size()); 3111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_EQ(NULL, 3121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci delegate_->GetTestModel()->FindFolderItem("single_item_folder")); 3131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 3141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// Test that an interrupted drag while reparenting an item from a folder, when 3166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// canceled via the root grid, correctly forwards the cancelation to the drag 3176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// ocurring from the folder. 3186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)TEST_F(AppListMainViewTest, MouseDragItemOutOfFolderWithCancel) { 3196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) CreateAndOpenSingleItemFolder(); 3206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) AppListItemView* dragged = StartDragForReparent(0); 3216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 3226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // Now add an item to the model, not in any folder, e.g., as if by Sync. 3236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) EXPECT_TRUE(RootGridView()->has_dragged_view()); 3246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) EXPECT_TRUE(FolderGridView()->has_dragged_view()); 3256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) delegate_->GetTestModel()->CreateAndAddItem("Extra"); 3266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 3276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // The drag operation should get canceled. 3286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) EXPECT_FALSE(RootGridView()->has_dragged_view()); 3296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) EXPECT_FALSE(FolderGridView()->has_dragged_view()); 3306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 3316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // Additional mouse move operations should be ignored. 3326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) gfx::Point point(1, 1); 3336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) SimulateUpdateDrag(FolderGridView(), AppsGridView::MOUSE, dragged, point); 3346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) EXPECT_FALSE(RootGridView()->has_dragged_view()); 3356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) EXPECT_FALSE(FolderGridView()->has_dragged_view()); 3366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 3376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 338a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} // namespace test 339a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} // namespace app_list 340