OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ui/app_list/views/app_list_main_view.h" | 5 #include "ui/app_list/views/app_list_main_view.h" |
6 | 6 |
7 #include "base/memory/scoped_ptr.h" | 7 #include "base/memory/scoped_ptr.h" |
8 #include "base/run_loop.h" | 8 #include "base/run_loop.h" |
9 #include "base/time/time.h" | 9 #include "base/time/time.h" |
10 #include "base/timer/timer.h" | 10 #include "base/timer/timer.h" |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
162 AppsGridView* FolderGridView() { return FolderView()->items_grid_view(); } | 162 AppsGridView* FolderGridView() { return FolderView()->items_grid_view(); } |
163 | 163 |
164 const views::ViewModel* RootViewModel() { | 164 const views::ViewModel* RootViewModel() { |
165 return RootGridView()->view_model_for_test(); | 165 return RootGridView()->view_model_for_test(); |
166 } | 166 } |
167 | 167 |
168 const views::ViewModel* FolderViewModel() { | 168 const views::ViewModel* FolderViewModel() { |
169 return FolderGridView()->view_model_for_test(); | 169 return FolderGridView()->view_model_for_test(); |
170 } | 170 } |
171 | 171 |
| 172 AppListItemView* CreateAndOpenSingleItemFolder() { |
| 173 // Prepare single folder with a single item in it. |
| 174 AppListFolderItem* folder_item = |
| 175 delegate_->GetTestModel()->CreateSingleItemFolder("single_item_folder", |
| 176 "single"); |
| 177 EXPECT_EQ(folder_item, |
| 178 delegate_->GetTestModel()->FindFolderItem("single_item_folder")); |
| 179 EXPECT_EQ(AppListFolderItem::kItemType, folder_item->GetItemType()); |
| 180 |
| 181 EXPECT_EQ(1, RootViewModel()->view_size()); |
| 182 AppListItemView* folder_item_view = |
| 183 static_cast<AppListItemView*>(RootViewModel()->view_at(0)); |
| 184 EXPECT_EQ(folder_item_view->item(), folder_item); |
| 185 |
| 186 // Click on the folder to open it. |
| 187 EXPECT_FALSE(FolderView()->visible()); |
| 188 SimulateClick(folder_item_view); |
| 189 base::RunLoop().RunUntilIdle(); |
| 190 EXPECT_TRUE(FolderView()->visible()); |
| 191 |
| 192 #if defined(OS_WIN) |
| 193 AppsGridViewTestApi folder_grid_view_test_api(FolderGridView()); |
| 194 folder_grid_view_test_api.DisableSynchronousDrag(); |
| 195 #endif |
| 196 return folder_item_view; |
| 197 } |
| 198 |
| 199 AppListItemView* StartDragForReparent(int index_in_folder) { |
| 200 // Start to drag the item in folder. |
| 201 views::View* item_view = FolderViewModel()->view_at(index_in_folder); |
| 202 gfx::Point point = item_view->bounds().CenterPoint(); |
| 203 AppListItemView* dragged = |
| 204 SimulateInitiateDrag(FolderGridView(), AppsGridView::MOUSE, point); |
| 205 EXPECT_EQ(item_view, dragged); |
| 206 EXPECT_FALSE(RootGridView()->visible()); |
| 207 EXPECT_TRUE(FolderView()->visible()); |
| 208 |
| 209 // Drag it to top left corner. |
| 210 point = gfx::Point(0, 0); |
| 211 // Two update drags needed to actually drag the view. The first changes |
| 212 // state and the 2nd one actually moves the view. The 2nd call can be |
| 213 // removed when UpdateDrag is fixed. |
| 214 SimulateUpdateDrag(FolderGridView(), AppsGridView::MOUSE, dragged, point); |
| 215 SimulateUpdateDrag(FolderGridView(), AppsGridView::MOUSE, dragged, point); |
| 216 base::RunLoop().RunUntilIdle(); |
| 217 |
| 218 // Wait until the folder view is invisible and root grid view shows up. |
| 219 GridViewVisibleWaiter(RootGridView()).Wait(); |
| 220 EXPECT_TRUE(RootGridView()->visible()); |
| 221 EXPECT_EQ(0, FolderView()->layer()->opacity()); |
| 222 |
| 223 return dragged; |
| 224 } |
| 225 |
172 protected: | 226 protected: |
173 views::Widget* widget_; // Owned by native window. | 227 views::Widget* widget_; // Owned by native window. |
174 AppListMainView* main_view_; // Owned by |widget_|. | 228 AppListMainView* main_view_; // Owned by |widget_|. |
175 scoped_ptr<AppListTestViewDelegate> delegate_; | 229 scoped_ptr<AppListTestViewDelegate> delegate_; |
176 | 230 |
177 private: | 231 private: |
178 DISALLOW_COPY_AND_ASSIGN(AppListMainViewTest); | 232 DISALLOW_COPY_AND_ASSIGN(AppListMainViewTest); |
179 }; | 233 }; |
180 | 234 |
181 } // namespace | 235 } // namespace |
182 | 236 |
183 // Tests changing the AppListModel when switching profiles. | 237 // Tests changing the AppListModel when switching profiles. |
184 TEST_F(AppListMainViewTest, ModelChanged) { | 238 TEST_F(AppListMainViewTest, ModelChanged) { |
185 delegate_->GetTestModel()->PopulateApps(kInitialItems); | 239 delegate_->GetTestModel()->PopulateApps(kInitialItems); |
186 EXPECT_EQ(kInitialItems, RootViewModel()->view_size()); | 240 EXPECT_EQ(kInitialItems, RootViewModel()->view_size()); |
187 | 241 |
188 // The model is owned by a profile keyed service, which is never destroyed | 242 // The model is owned by a profile keyed service, which is never destroyed |
189 // until after profile switching. | 243 // until after profile switching. |
190 scoped_ptr<AppListModel> old_model(delegate_->ReleaseTestModel()); | 244 scoped_ptr<AppListModel> old_model(delegate_->ReleaseTestModel()); |
191 | 245 |
192 const int kReplacementItems = 5; | 246 const int kReplacementItems = 5; |
193 delegate_->ReplaceTestModel(kReplacementItems); | 247 delegate_->ReplaceTestModel(kReplacementItems); |
194 main_view_->ModelChanged(); | 248 main_view_->ModelChanged(); |
195 EXPECT_EQ(kReplacementItems, RootViewModel()->view_size()); | 249 EXPECT_EQ(kReplacementItems, RootViewModel()->view_size()); |
196 } | 250 } |
197 | 251 |
198 // Tests dragging an item out of a single item folder and drop it at the last | 252 // Tests dragging an item out of a single item folder and drop it at the last |
199 // slot. | 253 // slot. |
200 TEST_F(AppListMainViewTest, DragLastItemFromFolderAndDropAtLastSlot) { | 254 TEST_F(AppListMainViewTest, DragLastItemFromFolderAndDropAtLastSlot) { |
201 // Prepare single folder with a single item in it. | 255 AppListItemView* folder_item_view = CreateAndOpenSingleItemFolder(); |
202 AppListFolderItem* folder_item = | |
203 delegate_->GetTestModel()->CreateSingleItemFolder("single_item_folder", | |
204 "single"); | |
205 EXPECT_EQ(folder_item, | |
206 delegate_->GetTestModel()->FindFolderItem("single_item_folder")); | |
207 EXPECT_EQ(AppListFolderItem::kItemType, folder_item->GetItemType()); | |
208 | |
209 EXPECT_EQ(1, RootViewModel()->view_size()); | |
210 AppListItemView* folder_item_view = | |
211 static_cast<AppListItemView*>(RootViewModel()->view_at(0)); | |
212 EXPECT_EQ(folder_item_view->item(), folder_item); | |
213 const gfx::Rect first_slot_tile = folder_item_view->bounds(); | 256 const gfx::Rect first_slot_tile = folder_item_view->bounds(); |
214 | 257 |
215 // Click on the folder to open it. | 258 EXPECT_EQ(1, FolderViewModel()->view_size()); |
216 EXPECT_FALSE(FolderView()->visible()); | |
217 SimulateClick(folder_item_view); | |
218 base::RunLoop().RunUntilIdle(); | |
219 EXPECT_TRUE(FolderView()->visible()); | |
220 | 259 |
221 #if defined(OS_WIN) | 260 AppListItemView* dragged = StartDragForReparent(0); |
222 AppsGridViewTestApi folder_grid_view_test_api(FolderGridView()); | |
223 folder_grid_view_test_api.DisableSynchronousDrag(); | |
224 #endif | |
225 | |
226 // Start to drag the item in folder. | |
227 EXPECT_EQ(1, FolderViewModel()->view_size()); | |
228 views::View* item_view = FolderViewModel()->view_at(0); | |
229 gfx::Point point = item_view->bounds().CenterPoint(); | |
230 AppListItemView* dragged = | |
231 SimulateInitiateDrag(FolderGridView(), AppsGridView::MOUSE, point); | |
232 EXPECT_EQ(item_view, dragged); | |
233 EXPECT_FALSE(RootGridView()->visible()); | |
234 EXPECT_TRUE(FolderView()->visible()); | |
235 | |
236 // Drag it to top left corner. | |
237 point = gfx::Point(0, 0); | |
238 // Two update drags needed to actually drag the view. The first changes state | |
239 // and the 2nd one actually moves the view. The 2nd call can be removed when | |
240 // UpdateDrag is fixed. | |
241 SimulateUpdateDrag(FolderGridView(), AppsGridView::MOUSE, dragged, point); | |
242 SimulateUpdateDrag(FolderGridView(), AppsGridView::MOUSE, dragged, point); | |
243 base::RunLoop().RunUntilIdle(); | |
244 | |
245 // Wait until the folder view is invisible and root grid view shows up. | |
246 GridViewVisibleWaiter(RootGridView()).Wait(); | |
247 EXPECT_TRUE(RootGridView()->visible()); | |
248 EXPECT_EQ(0, FolderView()->layer()->opacity()); | |
249 | 261 |
250 // Drop it to the slot on the right of first slot. | 262 // Drop it to the slot on the right of first slot. |
251 gfx::Rect drop_target_tile(first_slot_tile); | 263 gfx::Rect drop_target_tile(first_slot_tile); |
252 drop_target_tile.Offset(first_slot_tile.width(), 0); | 264 drop_target_tile.Offset(first_slot_tile.width(), 0); |
253 point = drop_target_tile.CenterPoint(); | 265 gfx::Point point = drop_target_tile.CenterPoint(); |
254 SimulateUpdateDrag(FolderGridView(), AppsGridView::MOUSE, dragged, point); | 266 SimulateUpdateDrag(FolderGridView(), AppsGridView::MOUSE, dragged, point); |
255 SimulateUpdateDrag(FolderGridView(), AppsGridView::MOUSE, dragged, point); | 267 SimulateUpdateDrag(FolderGridView(), AppsGridView::MOUSE, dragged, point); |
256 base::RunLoop().RunUntilIdle(); | 268 base::RunLoop().RunUntilIdle(); |
257 | 269 |
258 // Drop it. | 270 // Drop it. |
259 FolderGridView()->EndDrag(false); | 271 FolderGridView()->EndDrag(false); |
260 base::RunLoop().RunUntilIdle(); | 272 base::RunLoop().RunUntilIdle(); |
261 | 273 |
262 // Folder icon view should be gone and there is only one item view. | 274 // Folder icon view should be gone and there is only one item view. |
263 EXPECT_EQ(1, RootViewModel()->view_size()); | 275 EXPECT_EQ(1, RootViewModel()->view_size()); |
264 EXPECT_EQ(AppListItemView::kViewClassName, | 276 EXPECT_EQ(AppListItemView::kViewClassName, |
265 RootViewModel()->view_at(0)->GetClassName()); | 277 RootViewModel()->view_at(0)->GetClassName()); |
266 | 278 |
267 // The item view should be in slot 1 instead of slot 2 where it is dropped. | 279 // The item view should be in slot 1 instead of slot 2 where it is dropped. |
268 AppsGridViewTestApi root_grid_view_test_api(RootGridView()); | 280 AppsGridViewTestApi root_grid_view_test_api(RootGridView()); |
269 root_grid_view_test_api.LayoutToIdealBounds(); | 281 root_grid_view_test_api.LayoutToIdealBounds(); |
270 EXPECT_EQ(first_slot_tile, RootViewModel()->view_at(0)->bounds()); | 282 EXPECT_EQ(first_slot_tile, RootViewModel()->view_at(0)->bounds()); |
271 | 283 |
272 // Single item folder should be auto removed. | 284 // Single item folder should be auto removed. |
273 EXPECT_EQ(NULL, | 285 EXPECT_EQ(NULL, |
274 delegate_->GetTestModel()->FindFolderItem("single_item_folder")); | 286 delegate_->GetTestModel()->FindFolderItem("single_item_folder")); |
275 } | 287 } |
276 | 288 |
| 289 // Test that an interrupted drag while reparenting an item from a folder, when |
| 290 // canceled via the root grid, correctly forwards the cancelation to the drag |
| 291 // ocurring from the folder. |
| 292 TEST_F(AppListMainViewTest, MouseDragItemOutOfFolderWithCancel) { |
| 293 CreateAndOpenSingleItemFolder(); |
| 294 AppListItemView* dragged = StartDragForReparent(0); |
| 295 |
| 296 // Now add an item to the model, not in any folder, e.g., as if by Sync. |
| 297 EXPECT_TRUE(RootGridView()->has_dragged_view()); |
| 298 EXPECT_TRUE(FolderGridView()->has_dragged_view()); |
| 299 delegate_->GetTestModel()->CreateAndAddItem("Extra"); |
| 300 |
| 301 // The drag operation should get canceled. |
| 302 EXPECT_FALSE(RootGridView()->has_dragged_view()); |
| 303 EXPECT_FALSE(FolderGridView()->has_dragged_view()); |
| 304 |
| 305 // Additional mouse move operations should be ignored. |
| 306 gfx::Point point(1, 1); |
| 307 SimulateUpdateDrag(FolderGridView(), AppsGridView::MOUSE, dragged, point); |
| 308 EXPECT_FALSE(RootGridView()->has_dragged_view()); |
| 309 EXPECT_FALSE(FolderGridView()->has_dragged_view()); |
| 310 } |
| 311 |
277 } // namespace test | 312 } // namespace test |
278 } // namespace app_list | 313 } // namespace app_list |
OLD | NEW |