// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ash/app_list/views/apps_grid_view.h"

#include <stddef.h>

#include <memory>
#include <string>
#include <vector>

#include "ash/app_list/app_list_metrics.h"
#include "ash/app_list/app_list_test_view_delegate.h"
#include "ash/app_list/model/app_list_folder_item.h"
#include "ash/app_list/model/app_list_item.h"
#include "ash/app_list/model/app_list_model.h"
#include "ash/app_list/model/app_list_test_model.h"
#include "ash/app_list/model/search/test_search_result.h"
#include "ash/app_list/views/app_list_folder_view.h"
#include "ash/app_list/views/app_list_item_view.h"
#include "ash/app_list/views/app_list_main_view.h"
#include "ash/app_list/views/app_list_view.h"
#include "ash/app_list/views/apps_container_view.h"
#include "ash/app_list/views/apps_grid_view_folder_delegate.h"
#include "ash/app_list/views/apps_grid_view_test_api.h"
#include "ash/app_list/views/contents_view.h"
#include "ash/app_list/views/expand_arrow_view.h"
#include "ash/app_list/views/folder_background_view.h"
#include "ash/app_list/views/paged_apps_grid_view.h"
#include "ash/app_list/views/search_box_view.h"
#include "ash/app_list/views/search_result_tile_item_view.h"
#include "ash/app_list/views/suggestion_chip_container_view.h"
#include "ash/keyboard/ui/keyboard_ui_controller.h"
#include "ash/public/cpp/app_list/app_list_config.h"
#include "ash/public/cpp/app_list/app_list_features.h"
#include "ash/public/cpp/app_list/app_list_switches.h"
#include "ash/public/cpp/pagination/pagination_model.h"
#include "ash/public/cpp/presentation_time_recorder.h"
#include "ash/public/cpp/test/test_app_list_color_provider.h"
#include "base/command_line.h"
#include "base/compiler_specific.h"
#include "base/macros.h"
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/icu_test_util.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "build/build_config.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/aura/window.h"
#include "ui/compositor/layer.h"
#include "ui/events/event_utils.h"
#include "ui/views/controls/label.h"
#include "ui/views/controls/textfield/textfield.h"
#include "ui/views/test/views_test_base.h"

namespace ash {
namespace test {

namespace {

constexpr int kNumOfSuggestedApps = 3;

class PageFlipWaiter : public ash::PaginationModelObserver {
 public:
  explicit PageFlipWaiter(ash::PaginationModel* model) : model_(model) {
    model_->AddObserver(this);
  }

  ~PageFlipWaiter() override { model_->RemoveObserver(this); }

  void Wait() {
    DCHECK(!wait_);
    wait_ = true;

    ui_run_loop_ = std::make_unique<base::RunLoop>();
    ui_run_loop_->Run();
    wait_ = false;
  }

  void Reset() { selected_pages_.clear(); }

  const std::string& selected_pages() const { return selected_pages_; }

 private:
  // PaginationModelObserver overrides:
  void SelectedPageChanged(int old_selected, int new_selected) override {
    if (!selected_pages_.empty())
      selected_pages_ += ',';
    selected_pages_ += base::NumberToString(new_selected);

    if (wait_)
      ui_run_loop_->QuitWhenIdle();
  }

  std::unique_ptr<base::RunLoop> ui_run_loop_;
  ash::PaginationModel* model_ = nullptr;
  bool wait_ = false;
  std::string selected_pages_;

  DISALLOW_COPY_AND_ASSIGN(PageFlipWaiter);
};

// WindowDeletionWaiter waits for the specified window to be deleted.
class WindowDeletionWaiter : aura::WindowObserver {
 public:
  explicit WindowDeletionWaiter(aura::Window* window) : window_(window) {
    window_->AddObserver(this);
  }
  ~WindowDeletionWaiter() override = default;

  void Wait() { run_loop_.Run(); }

 private:
  // WindowObserver:
  void OnWindowDestroying(aura::Window* window) override {
    window->RemoveObserver(this);
    run_loop_.QuitWhenIdle();
  }

  base::RunLoop run_loop_;
  aura::Window* window_;

  DISALLOW_COPY_AND_ASSIGN(WindowDeletionWaiter);
};

// Find the window with type WINDOW_TYPE_MENU and returns the firstly found one.
// Returns nullptr if no such window exists.
aura::Window* FindMenuWindow(aura::Window* root) {
  if (root->GetType() == aura::client::WINDOW_TYPE_MENU)
    return root;
  for (auto* child : root->children()) {
    auto* menu_in_child = FindMenuWindow(child);
    if (menu_in_child)
      return menu_in_child;
  }
  return nullptr;
}

// Dragging task to be run after page flip is observed.
class DragAfterPageFlipTask : public ash::PaginationModelObserver {
 public:
  DragAfterPageFlipTask(ash::PaginationModel* model,
                        AppsGridView* view,
                        const ui::MouseEvent& drag_event)
      : model_(model), view_(view), drag_event_(drag_event) {
    model_->AddObserver(this);
  }

  ~DragAfterPageFlipTask() override { model_->RemoveObserver(this); }

 private:
  // PaginationModelObserver overrides:
  void TotalPagesChanged(int previous_page_count, int new_page_count) override {
  }
  void SelectedPageChanged(int old_selected, int new_selected) override {
    view_->UpdateDragFromItem(AppsGridView::MOUSE, drag_event_);
  }
  void TransitionStarted() override {}
  void TransitionChanged() override {}
  void TransitionEnded() override {}

  ash::PaginationModel* model_;
  AppsGridView* view_;
  ui::MouseEvent drag_event_;

  DISALLOW_COPY_AND_ASSIGN(DragAfterPageFlipTask);
};

class TestSuggestedSearchResult : public TestSearchResult {
 public:
  TestSuggestedSearchResult() {
    set_display_type(ash::SearchResultDisplayType::kChip);
    set_is_recommendation(true);
  }
  ~TestSuggestedSearchResult() override = default;

 private:
  DISALLOW_COPY_AND_ASSIGN(TestSuggestedSearchResult);
};

}  // namespace

class TestAppsGridViewFolderDelegate : public AppsGridViewFolderDelegate {
 public:
  TestAppsGridViewFolderDelegate() = default;
  TestAppsGridViewFolderDelegate(const TestAppsGridViewFolderDelegate&) =
      delete;
  TestAppsGridViewFolderDelegate& operator=(
      const TestAppsGridViewFolderDelegate&) = delete;
  ~TestAppsGridViewFolderDelegate() override = default;

  void ReparentItem(AppListItemView* original_drag_view,
                    const gfx::Point& drag_point_in_folder_grid,
                    bool has_native_drag) override {}

  void DispatchDragEventForReparent(
      AppsGridView::Pointer pointer,
      const gfx::Point& drag_point_in_folder_grid) override {}

  void DispatchEndDragEventForReparent(bool events_forwarded_to_drag_drop_host,
                                       bool cancel_drag) override {}

  bool IsViewOutsideOfFolder(AppListItemView* view) override { return false; }

  bool IsOEMFolder() const override { return false; }

  void SetRootLevelDragViewVisible(bool visible) override {}

  void HandleKeyboardReparent(AppListItemView* reparented_item,
                              ui::KeyboardCode key_code) override {}
  void UpdateFolderBounds() override {}
};

class AppsGridViewTest : public views::ViewsTestBase {
 public:
  AppsGridViewTest() = default;
  AppsGridViewTest(bool is_rtl,
                   bool is_pagination_preview_active,
                   bool create_as_tablet_mode)
      : is_rtl_(is_rtl),
        is_pagination_preview_active_(is_pagination_preview_active),
        create_as_tablet_mode_(create_as_tablet_mode) {}
  AppsGridViewTest(const AppsGridViewTest&) = delete;
  AppsGridViewTest& operator=(const AppsGridViewTest&) = delete;
  ~AppsGridViewTest() override = default;

  // testing::Test overrides:
  void SetUp() override {
    AppListView::SetShortAnimationForTesting(true);
    if (is_rtl_)
      base::i18n::SetICUDefaultLocale("he");
    feature_list.InitWithFeatureState(app_list_features::kNewDragSpecInLauncher,
                                      is_pagination_preview_active_);
    views::ViewsTestBase::SetUp();
    gfx::NativeView parent = GetContext();
    // Ensure that parent is big enough to show the full AppListView.
    parent->SetBounds(gfx::Rect(gfx::Point(0, 0), gfx::Size(1024, 768)));
    delegate_ = std::make_unique<AppListTestViewDelegate>();
    delegate_->SetIsTabletModeEnabled(create_as_tablet_mode_);
    app_list_view_ = new AppListView(delegate_.get());
    app_list_view_->InitView(parent);
    app_list_view_->Show(AppListViewState::kFullscreenAllApps,
                         false /*is_side_shelf*/);
    contents_view_ = app_list_view_->app_list_main_view()->contents_view();
    apps_grid_view_ = contents_view_->apps_container_view()->apps_grid_view();
    app_list_view_->GetWidget()->Show();

    model_ = delegate_->GetTestModel();
    search_model_ = delegate_->GetSearchModel();
    suggestions_container_ = contents_view_->apps_container_view()
                                 ->suggestion_chip_container_view_for_test();
    expand_arrow_view_ = contents_view_->expand_arrow_view();
    for (size_t i = 0; i < kNumOfSuggestedApps; ++i) {
      search_model_->results()->Add(
          std::make_unique<TestSuggestedSearchResult>());
    }
    // Needed to update suggestions from |model_|.
    suggestions_container_->Update();

    test_api_ = std::make_unique<AppsGridViewTestApi>(apps_grid_view_);
    ash::PresentationTimeRecorder::SetReportPresentationTimeImmediatelyForTest(
        true);

    // In production, page flip duration > page transition > overscroll.
    SetPageFlipDurationForTest(apps_grid_view_);
    page_flip_waiter_ = std::make_unique<PageFlipWaiter>(GetPaginationModel());
  }

  void TearDown() override {
    page_flip_waiter_.reset();
    ash::PresentationTimeRecorder::SetReportPresentationTimeImmediatelyForTest(
        false);
    app_list_view_->GetWidget()->Close();
    views::ViewsTestBase::TearDown();
    AppListView::SetShortAnimationForTesting(false);
  }

 protected:
  void AnimateFolderViewPageFlip(int target_page) {
    DCHECK(folder_apps_grid_view()->pagination_model()->total_pages() >
           target_page);
    AppsGridViewTestApi folder_grid_test_api(folder_apps_grid_view());
    SetPageFlipDurationForTest(folder_apps_grid_view());
    PageFlipWaiter page_flip_waiter(
        folder_apps_grid_view()->pagination_model());
    folder_apps_grid_view()->pagination_model()->SelectPage(target_page,
                                                            true /*animate*/);
    while (HasPendingPageFlip(folder_apps_grid_view())) {
      page_flip_waiter.Wait();
    }
    folder_grid_test_api.LayoutToIdealBounds();
  }

  void SetPageFlipDurationForTest(PagedAppsGridView* apps_grid_view) {
    apps_grid_view->set_page_flip_delay_for_testing(
        base::TimeDelta::FromMilliseconds(3));
    apps_grid_view->pagination_model()->SetTransitionDurations(
        base::TimeDelta::FromMilliseconds(2),
        base::TimeDelta::FromMilliseconds(1));
  }

  bool HasPendingPageFlip(PagedAppsGridView* apps_grid_view) {
    return apps_grid_view->page_flip_timer_.IsRunning() ||
           apps_grid_view->pagination_model()->has_transition();
  }

  const AppListConfig& GetAppListConfig() const {
    return contents_view_->GetAppListConfig();
  }

  AppListItemView* GetItemViewInAppsGridAt(int index,
                                           AppsGridView* grid_view) const {
    return grid_view->view_model()->view_at(index);
  }

  AppListItemView* GetItemViewInTopLevelGrid(int index) const {
    return GetItemViewInAppsGridAt(index, apps_grid_view_);
  }

  AppListItemView* GetItemViewInAppsGridForPoint(
      const gfx::Point& point,
      AppsGridView* grid_view) const {
    std::unique_ptr<AppsGridViewTestApi> temp_test_api =
        std::make_unique<AppsGridViewTestApi>(grid_view);
    const int selected_page = grid_view->pagination_model()->selected_page();
    for (int i = 0; i < temp_test_api->AppsOnPage(selected_page); ++i) {
      GridIndex index(selected_page, i);
      AppListItemView* view = grid_view->GetViewAtIndex(index);
      gfx::Point view_origin = view->origin();
      // AppListItemViews on non-zero'th pages of AppsGridViews have offset
      // coordinates that need to be converted to target.
      if (selected_page != 0) {
        views::View::ConvertPointToTarget(view->parent(), grid_view,
                                          &view_origin);
        // AppListItemViews that belong to a folder views' AppsGridView also
        // need to have their x coordinate set for RTL.
        if (grid_view->IsInFolder())
          view_origin.set_x(grid_view->GetMirroredXInView(view_origin.x()));
      }
      if (gfx::Rect(view_origin, view->size()).Contains(point))
        return view;
    }
    return nullptr;
  }

  AppListItemView* GetItemViewForPoint(const gfx::Point& point) const {
    return GetItemViewInAppsGridForPoint(point, apps_grid_view_);
  }

  gfx::Rect GetItemRectOnCurrentPageAt(int row, int col) const {
    DCHECK_GT(model_->top_level_item_list()->item_count(), 0u);
    return test_api_->GetItemTileRectOnCurrentPageAt(row, col);
  }

  int GetTilesPerPage() const { return test_api_->TilesPerPage(); }

  ash::PaginationModel* GetPaginationModel() const {
    return apps_grid_view_->pagination_model();
  }

  AppListFolderView* app_list_folder_view() const {
    return contents_view_->apps_container_view()->app_list_folder_view();
  }

  PagedAppsGridView* folder_apps_grid_view() const {
    return app_list_folder_view()->items_grid_view();
  }

  void SimulateKeyPress(ui::KeyboardCode key_code) {
    SimulateKeyPress(key_code, ui::EF_NONE);
  }

  void SimulateKeyPress(ui::KeyboardCode key_code, int flags) {
    ui::KeyEvent key_event(ui::ET_KEY_PRESSED, key_code, flags);
    apps_grid_view_->OnKeyPressed(key_event);
  }

  void SimulateKeyReleased(ui::KeyboardCode key_code, int flags) {
    ui::KeyEvent key_event(ui::ET_KEY_RELEASED, key_code, flags);
    apps_grid_view_->OnKeyReleased(key_event);
  }

  // Points are in |apps_grid_view_|'s coordinates, and fixed for RTL.
  ui::GestureEvent SimulateTap(const gfx::Point& location) {
    ui::GestureEvent gesture_event(
        apps_grid_view_->GetMirroredXInView(location.x()), location.y(), 0,
        base::TimeTicks(), ui::GestureEventDetails(ui::ET_GESTURE_TAP));
    apps_grid_view_->OnGestureEvent(&gesture_event);
    return gesture_event;
  }

  // Tests that the order of item views in the AppsGridView is in accordance
  // with the order in the view model.
  void TestAppListItemViewIndice() {
    const views::ViewModelT<AppListItemView>* view_model =
        apps_grid_view_->view_model();
    DCHECK_GT(view_model->view_size(), 0);
    views::View* items_container = apps_grid_view_->items_container_;
    auto app_iter = items_container->FindChild(view_model->view_at(0));
    DCHECK(app_iter != items_container->children().cend());
    for (int i = 1; i < view_model->view_size(); ++i) {
      ++app_iter;
      ASSERT_NE(items_container->children().cend(), app_iter);
      EXPECT_EQ(view_model->view_at(i), *app_iter);
    }
  }

  // Calls the private method.
  static void DeleteItemAt(AppListItemList* item_list, size_t index) {
    item_list->DeleteItemAt(index);
  }

  // Calls the private method.
  void MoveItemInModel(AppListItemView* item_view, const GridIndex& target) {
    apps_grid_view_->MoveItemInModel(item_view, target);
  }

  TestAppListColorProvider color_provider_;      // Needed by AppListView.
  AppListView* app_list_view_ = nullptr;         // Owned by native widget.
  PagedAppsGridView* apps_grid_view_ = nullptr;  // Owned by |app_list_view_|.
  ContentsView* contents_view_ = nullptr;        // Owned by |app_list_view_|.
  SearchResultContainerView* suggestions_container_ =
      nullptr;                                    // Owned by |apps_grid_view_|.
  ExpandArrowView* expand_arrow_view_ = nullptr;  // Owned by |apps_grid_view_|.
  std::unique_ptr<AppListTestViewDelegate> delegate_;
  AppListTestModel* model_ = nullptr;    // Owned by |delegate_|.
  SearchModel* search_model_ = nullptr;  // Owned by |delegate_|.
  std::unique_ptr<AppsGridViewTestApi> test_api_;

  // True if the test screen is configured to work with RTL locale.
  bool is_rtl_ = false;
  // True if the launcher pagination preview is enabled for the test.
  bool is_pagination_preview_active_ = false;
  // True if the test shoould run with fullscreen.
  bool test_with_fullscreen_ = true;
  // True if we set the test on tablet mode.
  bool create_as_tablet_mode_ = false;

  std::unique_ptr<PageFlipWaiter> page_flip_waiter_;

 private:
  // Restores the locale to default when destructor is called.
  base::test::ScopedRestoreICUDefaultLocale restore_locale_;

  // Used by AppListFolderView::UpdatePreferredBounds.
  keyboard::KeyboardUIController keyboard_ui_controller_;

  base::test::ScopedFeatureList feature_list;
};

// Tests suite for verifying UI behaviour on RTL.
class AppsGridViewRTLTest : public AppsGridViewTest,
                            public testing::WithParamInterface<bool> {
 public:
  AppsGridViewRTLTest()
      : AppsGridViewTest(/*is_rtl=*/GetParam(),
                         /*is_pagination_preview_active_=*/false,
                         /*create_as_tablet_mode=*/false) {}
  explicit AppsGridViewRTLTest(bool create_as_tablet_mode)
      : AppsGridViewTest(/*is_rtl=*/GetParam(),
                         /*is_pagination_preview_active_=*/false,
                         create_as_tablet_mode) {}
  AppsGridViewRTLTest(const AppsGridViewRTLTest&) = delete;
  AppsGridViewRTLTest& operator=(const AppsGridViewRTLTest&) = delete;
  ~AppsGridViewRTLTest() override = default;
};

INSTANTIATE_TEST_SUITE_P(All, AppsGridViewRTLTest, testing::Bool());

// Test base for app list items drag and drop tests. The suite contains helper
// methods to deal with drag and drop logic.
class AppsGridViewDragAndDropTestBase : public AppsGridViewTest {
 public:
  AppsGridViewDragAndDropTestBase(bool is_rtl,
                                  bool is_pagination_preview_active)
      : AppsGridViewTest(is_rtl,
                         is_pagination_preview_active,
                         /*create_as_tablet_mode=*/false) {}
  AppsGridViewDragAndDropTestBase(const AppsGridViewDragAndDropTestBase&) =
      delete;
  AppsGridViewDragAndDropTestBase& operator=(
      const AppsGridViewDragAndDropTestBase&) = delete;
  ~AppsGridViewDragAndDropTestBase() override = default;

  AppListItemView* InitiateDrag(AppsGridView::Pointer pointer,
                                const gfx::Point& from,
                                AppsGridView* apps_grid_view) {
    AppListItemView* view = GetItemViewInAppsGridForPoint(from, apps_grid_view);
    DCHECK(view);
    gfx::Point root_from(from);
    gfx::NativeWindow window = app_list_view_->GetWidget()->GetNativeWindow();
    views::View::ConvertPointToWidget(apps_grid_view, &root_from);
    aura::Window::ConvertPointToTarget(window, window->GetRootWindow(),
                                       &root_from);
    // Ensure that the |root_from| point is correct if RTL.
    root_from.set_x(apps_grid_view->GetMirroredXInView(root_from.x()));

    apps_grid_view->InitiateDrag(view, root_from, root_from);
    current_drag_location_ = root_from;
    // Call UpdateDrag to trigger |apps_grid_view| change to cardified_state.
    UpdateDrag(pointer, from, apps_grid_view);
    return view;
  }

  // Updates the drag from the current drag location to the destination point
  // |to|. These coordinates are relative the |apps_grid_view| which may belong
  // to either the app list or an open folder view.
  void UpdateDrag(AppsGridView::Pointer pointer,
                  const gfx::Point& to,
                  AppsGridView* apps_grid_view,
                  int steps = 1) {
    // Check that the drag has been initialized.
    DCHECK(current_drag_location_);
    gfx::Point root_to(to);
    gfx::NativeWindow window = apps_grid_view->GetWidget()->GetNativeWindow();
    views::View::ConvertPointToWidget(apps_grid_view, &root_to);
    aura::Window::ConvertPointToTarget(window, window->GetRootWindow(),
                                       &root_to);
    // Ensure that the |root_to| point is correct if RTL.
    root_to.set_x(apps_grid_view->GetMirroredXInView(root_to.x()));

    for (int step = 1; step <= steps; step += 1) {
      gfx::Point drag_increment_point(*current_drag_location_);
      drag_increment_point += gfx::Vector2d(
          (root_to.x() - current_drag_location_->x()) * step / steps,
          (root_to.y() - current_drag_location_->y()) * step / steps);
      ui::MouseEvent drag_event(ui::ET_MOUSE_DRAGGED, to, drag_increment_point,
                                ui::EventTimeForNow(), 0, 0);
      apps_grid_view->UpdateDragFromItem(pointer, drag_event);
    }

    current_drag_location_ = root_to;
  }

  void EndDrag(AppsGridView* grid_view, bool cancel) {
    grid_view->EndDrag(cancel);
    current_drag_location_ = absl::nullopt;
  }

  // Points are in |apps_grid_view_|'s coordinates, and fixed for RTL.
  AppListItemView* SimulateDrag(AppsGridView::Pointer pointer,
                                const gfx::Point& from,
                                const gfx::Point& to) {
    AppListItemView* view = InitiateDrag(pointer, from, apps_grid_view_);
    UpdateDrag(pointer, to, apps_grid_view_);
    return view;
  }

  // Simulate drag from the |from| point to either next or previous page's |to|
  // point.
  // Update drag to either next or previous page's |to| point.
  void UpdateDragToNeighborPage(bool next_page, const gfx::Point& to) {
    const int selected_page = GetPaginationModel()->selected_page();
    DCHECK(selected_page >= 0 &&
           selected_page <= GetPaginationModel()->total_pages());

    // Calculate the point required to flip the page if an item is dragged to
    // it.
    const gfx::Rect apps_grid_bounds = apps_grid_view_->GetLocalBounds();
    gfx::Point point_in_page_flip_buffer =
        gfx::Point(apps_grid_bounds.width() / 2,
                   next_page ? apps_grid_bounds.bottom() + 1 : 0);

    // Build the drag event which will be triggered after page flip.
    gfx::Point root_to(to);
    views::View::ConvertPointToWidget(apps_grid_view_, &root_to);
    gfx::NativeWindow window = app_list_view_->GetWidget()->GetNativeWindow();
    aura::Window::ConvertPointToTarget(window, window->GetRootWindow(),
                                       &root_to);
    root_to.set_x(apps_grid_view_->GetMirroredXInView(root_to.x()));
    ui::MouseEvent drag_event(ui::ET_MOUSE_DRAGGED, to, root_to,
                              ui::EventTimeForNow(), 0, 0);

    // Update dragging and relayout apps grid view after drag ends.
    DragAfterPageFlipTask task(GetPaginationModel(), apps_grid_view_,
                               drag_event);
    page_flip_waiter_->Reset();
    UpdateDrag(AppsGridView::MOUSE, point_in_page_flip_buffer, apps_grid_view_,
               /*steps=*/10);
    while (HasPendingPageFlip(apps_grid_view_)) {
      page_flip_waiter_->Wait();
    }
    EndDrag(apps_grid_view_, false /*cancel*/);
    test_api_->LayoutToIdealBounds();
  }

  gfx::Point GetDragViewCenter() {
    gfx::Point drag_view_center =
        apps_grid_view_->drag_view()->GetLocalBounds().CenterPoint();
    views::View::ConvertPointToTarget(apps_grid_view_->drag_view(),
                                      apps_grid_view_, &drag_view_center);
    return drag_view_center;
  }

 private:
  absl::optional<gfx::Point> current_drag_location_;
};

// Tests suite for app list items drag and drop tests. These tests are
// paramerized to cover both RTL locale and pagination previews behaviour.
class AppsGridViewDragAndDropTest
    : public AppsGridViewDragAndDropTestBase,
      public testing::WithParamInterface<std::tuple<bool, bool>> {
 public:
  AppsGridViewDragAndDropTest()
      : AppsGridViewDragAndDropTestBase(
            /*is_rtl=*/std::get<0>(GetParam()),
            /*is_pagination_preview_active_=*/std::get<1>(GetParam())) {}
  AppsGridViewDragAndDropTest(const AppsGridViewDragAndDropTest&) = delete;
  AppsGridViewDragAndDropTest& operator=(const AppsGridViewDragAndDropTest&) =
      delete;
  ~AppsGridViewDragAndDropTest() override = default;
};

INSTANTIATE_TEST_SUITE_P(All,
                         AppsGridViewDragAndDropTest,
                         testing::Combine(testing::Bool(), testing::Bool()));

// Tests suite for app list items drag and drop tests. These tests are not
// proved to work with a cardified state.
// TODO(anasalazar): Fix tests under this suite to work with a cardified state
class AppsGridViewDragAndDropTestNoCardifiedState
    : public AppsGridViewDragAndDropTestBase,
      public testing::WithParamInterface<bool> {
 public:
  AppsGridViewDragAndDropTestNoCardifiedState()
      : AppsGridViewDragAndDropTestBase(
            /*is_rtl=*/GetParam(),
            /*is_pagination_preview_active_=*/false) {}
  AppsGridViewDragAndDropTestNoCardifiedState(
      const AppsGridViewDragAndDropTestNoCardifiedState&) = delete;
  AppsGridViewDragAndDropTestNoCardifiedState& operator=(
      const AppsGridViewDragAndDropTestNoCardifiedState&) = delete;
  ~AppsGridViewDragAndDropTestNoCardifiedState() override = default;
};

INSTANTIATE_TEST_SUITE_P(All,
                         AppsGridViewDragAndDropTestNoCardifiedState,
                         testing::Bool());

// Tests suite to verify behaviour exclusively to cardified state.
class AppsGridViewCardifiedStateTest
    : public AppsGridViewDragAndDropTestBase,
      public testing::WithParamInterface<bool> {
 public:
  AppsGridViewCardifiedStateTest()
      : AppsGridViewDragAndDropTestBase(
            /*is_rtl=*/GetParam(),
            /*is_pagination_preview_active_=*/true) {}
  AppsGridViewCardifiedStateTest(const AppsGridViewCardifiedStateTest&) =
      delete;
  AppsGridViewCardifiedStateTest& operator=(
      const AppsGridViewCardifiedStateTest&) = delete;
  ~AppsGridViewCardifiedStateTest() override = default;
};

INSTANTIATE_TEST_SUITE_P(All, AppsGridViewCardifiedStateTest, testing::Bool());

// Test suite for verifying tablet mode apps grid behaviour.
class AppsGridViewTabletTest : public AppsGridViewRTLTest {
 public:
  AppsGridViewTabletTest()
      : AppsGridViewRTLTest(/*create_as_tablet_mode=*/true) {}
  AppsGridViewTabletTest(const AppsGridViewTabletTest&) = delete;
  AppsGridViewTabletTest& operator=(const AppsGridViewTabletTest&) = delete;
  ~AppsGridViewTabletTest() override = default;
};
INSTANTIATE_TEST_SUITE_P(All, AppsGridViewTabletTest, testing::Bool());

TEST_F(AppsGridViewTest, CreatePage) {
  // Fully populates a page.
  const int kPages = 1;

  EXPECT_EQ(kNumOfSuggestedApps, suggestions_container_->num_results());
  // For new style launcher, each page has the same number of rows.
  const int kExpectedTilesOnFirstPage =
      apps_grid_view_->cols() * (apps_grid_view_->rows_per_page());
  EXPECT_EQ(kExpectedTilesOnFirstPage, GetTilesPerPage());

  model_->PopulateApps(kPages * GetTilesPerPage());
  EXPECT_EQ(kPages, GetPaginationModel()->total_pages());

  // Adds one more and gets a new page created.
  model_->CreateAndAddItem("Extra");
  EXPECT_EQ(kPages + 1, GetPaginationModel()->total_pages());
}

TEST_F(AppsGridViewTest, RemoveSelectedLastApp) {
  const int kTotalItems = 2;
  const int kLastItemIndex = kTotalItems - 1;

  model_->PopulateApps(kTotalItems);

  AppListItemView* last_view = GetItemViewInTopLevelGrid(kLastItemIndex);
  apps_grid_view_->SetSelectedView(last_view);
  model_->DeleteItem(model_->GetItemName(kLastItemIndex));

  EXPECT_FALSE(apps_grid_view_->IsSelectedView(last_view));

  // No crash happens.
  AppListItemView* view = GetItemViewInTopLevelGrid(0);
  apps_grid_view_->SetSelectedView(view);
  EXPECT_TRUE(apps_grid_view_->IsSelectedView(view));
}

// Tests that UMA is properly collected when either a suggested or normal app is
// launched.
TEST_F(AppsGridViewTest, UMATestForLaunchingApps) {
  base::HistogramTester histogram_tester;
  model_->PopulateApps(5);

  // Select the first app in grid and launch it.
  contents_view_->GetAppListMainView()->ActivateApp(
      GetItemViewInTopLevelGrid(0)->item(), 0);

  // Test that histogram recorded app launch from grid.
  histogram_tester.ExpectBucketCount(
      "Apps.AppListAppLaunchedV2.FullscreenAllApps", 1 /* kAppListItem */,
      1 /* Times kAppListItem launched */);

  // Launch a suggested app.
  suggestions_container_->children().front()->OnKeyPressed(
      ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_RETURN, ui::EF_NONE));

  // Test that histogram recorded app launched from suggestion chip.
  histogram_tester.ExpectBucketCount(
      "Apps.AppListAppLaunchedV2.FullscreenAllApps", 2 /* kSuggestionChip */,
      1 /* Times kSuggestionChip Launched */);
}

// Tests that the item list changed without user operations; this happens on
// active user switch. See https://crbug.com/980082.
TEST_F(AppsGridViewTest, MoveItemAcrossRowDoesNotCauseCrash) {
  const int cols = apps_grid_view_->cols();
  ASSERT_LE(0, cols);
  model_->PopulateApps(cols * 2);

  AppListItemView* view0 = GetItemViewInTopLevelGrid(0);
  model_->top_level_item_list()->MoveItem(0, cols + 2);

  // Make sure the logical location of the view.
  EXPECT_NE(view0, GetItemViewInTopLevelGrid(0));
  EXPECT_EQ(view0, GetItemViewInTopLevelGrid(cols + 2));

  // |view0| should be animating with layer.
  EXPECT_TRUE(view0->layer());

  test_api_->WaitForItemMoveAnimationDone();
  // |view0| layer should be cleared after the animation.
  EXPECT_FALSE(view0->layer());
  EXPECT_EQ(view0->bounds(), GetItemRectOnCurrentPageAt(1, 2));
}

TEST_F(AppsGridViewTest, MoveItemAcrossRowDoesNotCauseAnimation) {
  const int cols = apps_grid_view_->cols();
  ASSERT_LE(0, cols);
  model_->PopulateApps(cols * 2);

  apps_grid_view_->GetWidget()->Hide();

  AppListItemView* view0 = GetItemViewInTopLevelGrid(0);
  model_->top_level_item_list()->MoveItem(0, cols + 2);

  // Make sure the logical location of the view.
  EXPECT_NE(view0, GetItemViewInTopLevelGrid(0));
  EXPECT_EQ(view0, GetItemViewInTopLevelGrid(cols + 2));

  // The item should be repositioned immediately when the widget is not visible.
  EXPECT_FALSE(view0->layer());
  EXPECT_EQ(view0->bounds(), GetItemRectOnCurrentPageAt(1, 2));
}

// Tests that control + arrow while a suggested chip is focused does not crash.
TEST_F(AppsGridViewTest, ControlArrowOnSuggestedChip) {
  model_->PopulateApps(5);
  suggestions_container_->children().front()->RequestFocus();

  SimulateKeyPress(ui::VKEY_UP, ui::EF_CONTROL_DOWN);

  EXPECT_EQ(suggestions_container_->children().front(),
            apps_grid_view_->GetFocusManager()->GetFocusedView());
}

TEST_F(AppsGridViewTest, ItemLabelShortNameOverride) {
  // If the app's full name and short name differ, the title label's tooltip
  // should always be the full name of the app.
  std::string expected_text("xyz");
  std::string expected_tooltip("tooltip");
  AppListItem* item = model_->CreateAndAddItem("Item with short name");
  model_->SetItemNameAndShortName(item, expected_tooltip, expected_text);

  AppListItemView* item_view = GetItemViewInTopLevelGrid(0);
  ASSERT_TRUE(item_view);
  const views::Label* title_label = item_view->title();
  EXPECT_EQ(base::ASCIIToUTF16(expected_tooltip),
            item_view->GetTooltipText(title_label->bounds().CenterPoint()));
  EXPECT_EQ(base::ASCIIToUTF16(expected_text), title_label->GetText());
}

TEST_F(AppsGridViewTest, ItemLabelNoShortName) {
  // If the app's full name and short name are the same, use the default tooltip
  // behavior of the label (only show a tooltip if the title is truncated).
  std::string title("a");
  AppListItem* item = model_->CreateAndAddItem(title);
  model_->SetItemNameAndShortName(item, title, "");

  AppListItemView* item_view = GetItemViewInTopLevelGrid(0);
  ASSERT_TRUE(item_view);
  const views::Label* title_label = item_view->title();
  EXPECT_TRUE(
      title_label->GetTooltipText(title_label->bounds().CenterPoint()).empty());
  EXPECT_EQ(base::ASCIIToUTF16(title), title_label->GetText());
}

TEST_P(AppsGridViewRTLTest, ScrollSequenceHandledByAppListView) {
  base::HistogramTester histogram_tester;

  model_->PopulateApps(GetTilesPerPage() + 1);
  EXPECT_EQ(2, GetPaginationModel()->total_pages());

  gfx::Point apps_grid_view_origin =
      apps_grid_view_->GetBoundsInScreen().origin();
  ui::GestureEvent scroll_begin(
      apps_grid_view_origin.x(), apps_grid_view_origin.y(), 0,
      base::TimeTicks(),
      ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_BEGIN, 0, 1));
  ui::GestureEvent scroll_update(
      apps_grid_view_origin.x(), apps_grid_view_origin.y(), 0,
      base::TimeTicks(),
      ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_UPDATE, 0, 10));
  ui::GestureEvent scroll_end(apps_grid_view_origin.x(),
                              apps_grid_view_origin.y(), 0, base::TimeTicks(),
                              ui::GestureEventDetails(ui::ET_GESTURE_END));

  // Drag down on the app grid when on page 1, this should move the AppListView
  // and not move the AppsGridView.
  apps_grid_view_->OnGestureEvent(&scroll_begin);
  EXPECT_FALSE(scroll_begin.handled());

  // Simulate redirecting the event to app list view through views hierarchy.
  app_list_view_->OnGestureEvent(&scroll_begin);
  EXPECT_TRUE(scroll_begin.handled());
  histogram_tester.ExpectTotalCount(
      "Apps.StateTransition.Drag.PresentationTime.ClamshellMode", 0);

  // The following scroll update events will be sent to the view that handled
  // the scroll begin event.
  app_list_view_->OnGestureEvent(&scroll_update);
  EXPECT_TRUE(scroll_update.handled());
  ASSERT_TRUE(app_list_view_->is_in_drag());
  ASSERT_EQ(0, GetPaginationModel()->transition().progress);
  histogram_tester.ExpectTotalCount(
      "Apps.StateTransition.Drag.PresentationTime.ClamshellMode", 1);
  histogram_tester.ExpectTotalCount(
      "Apps.StateTransition.Drag.PresentationTime.MaxLatency.ClamshellMode", 0);

  app_list_view_->OnGestureEvent(&scroll_end);
  EXPECT_TRUE(scroll_end.handled());

  histogram_tester.ExpectTotalCount(
      "Apps.StateTransition.Drag.PresentationTime.ClamshellMode", 1);
  histogram_tester.ExpectTotalCount(
      "Apps.StateTransition.Drag.PresentationTime.MaxLatency.ClamshellMode", 1);
}

TEST_P(AppsGridViewRTLTest, MouseScrollSequenceHandledByAppListView) {
  base::HistogramTester histogram_tester;

  model_->PopulateApps(GetTilesPerPage() + 1);
  EXPECT_EQ(2, GetPaginationModel()->total_pages());

  const gfx::Point apps_grid_view_origin =
      apps_grid_view_->GetBoundsInScreen().origin();
  // Pick a point inside the `AppsGridView`, as well as arbitrary points below
  // and above it to drag to.
  gfx::Point drag_start_point = apps_grid_view_origin + gfx::Vector2d(0, 10);
  gfx::Point below_point = apps_grid_view_origin + gfx::Vector2d(0, 20);
  gfx::Point above_point = apps_grid_view_origin + gfx::Vector2d(0, -20);

  ui::MouseEvent press_event(ui::ET_MOUSE_PRESSED, apps_grid_view_origin,
                             apps_grid_view_origin, ui::EventTimeForNow(),
                             ui::EF_LEFT_MOUSE_BUTTON,
                             ui::EF_LEFT_MOUSE_BUTTON);

  ui::MouseEvent drag_start(ui::ET_MOUSE_DRAGGED, drag_start_point,
                            drag_start_point, ui::EventTimeForNow(),
                            ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);

  ui::MouseEvent drag_below(ui::ET_MOUSE_DRAGGED, below_point, below_point,
                            ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON,
                            ui::EF_LEFT_MOUSE_BUTTON);

  ui::MouseEvent drag_above(ui::ET_MOUSE_DRAGGED, above_point, above_point,
                            ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON,
                            ui::EF_LEFT_MOUSE_BUTTON);

  // Send a press event to set the `mouse_drag_start_point_` for scrolling
  apps_grid_view_->OnMouseEvent(&press_event);
  EXPECT_TRUE(press_event.handled());

  // Drag down on the app grid when on page 1, this should move the
  // `AppListView` and not move the `AppsGridView`. We have to send two drag
  // down events, `drag_start` and `drag_below`, to make sure `AppListView` has
  // its anchor point and starts dragging down. Event is manually passed to
  // `AppListview` in `AppsGridView::OnMouseEvent`
  apps_grid_view_->OnMouseEvent(&drag_start);
  EXPECT_TRUE(drag_start.handled());
  histogram_tester.ExpectTotalCount(
      "Apps.StateTransition.Drag.PresentationTime.ClamshellMode", 0);

  apps_grid_view_->OnMouseEvent(&drag_below);
  EXPECT_TRUE(drag_below.handled());
  ASSERT_TRUE(app_list_view_->is_in_drag());
  ASSERT_EQ(0, GetPaginationModel()->transition().progress);
  histogram_tester.ExpectTotalCount(
      "Apps.StateTransition.Drag.PresentationTime.ClamshellMode", 1);
  histogram_tester.ExpectTotalCount(
      "Apps.StateTransition.Drag.PresentationTime.MaxLatency.ClamshellMode", 0);

  // Now drag back up. Because we have dragged the launcher down, we want it to
  // continue dragging to allow the user to fully expand it. If we don't, the
  // launcher can end up in a "expanded" state with the launcher not reaching
  // the top of the screen and the app list scrolling.
  apps_grid_view_->OnMouseEvent(&drag_above);
  EXPECT_TRUE(drag_above.handled());
  ASSERT_TRUE(app_list_view_->is_in_drag());
  ASSERT_EQ(0, GetPaginationModel()->transition().progress);
  histogram_tester.ExpectTotalCount(
      "Apps.StateTransition.Drag.PresentationTime.ClamshellMode", 2);
  histogram_tester.ExpectTotalCount(
      "Apps.StateTransition.Drag.PresentationTime.MaxLatency.ClamshellMode", 0);
}

TEST_P(AppsGridViewRTLTest,
       OnGestureEventScrollSequenceHandleByPaginationController) {
  base::HistogramTester histogram_tester;

  model_->PopulateApps(GetTilesPerPage() + 1);
  EXPECT_EQ(2, GetPaginationModel()->total_pages());

  gfx::Point apps_grid_view_origin =
      apps_grid_view_->GetBoundsInScreen().origin();
  ui::GestureEvent scroll_begin(
      apps_grid_view_origin.x(), apps_grid_view_origin.y(), 0,
      base::TimeTicks(),
      ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_BEGIN, 0, -1));
  ui::GestureEvent scroll_update(
      apps_grid_view_origin.x(), apps_grid_view_origin.y(), 0,
      base::TimeTicks(),
      ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_UPDATE, 0, -10));
  ui::GestureEvent scroll_end(
      apps_grid_view_origin.x(), apps_grid_view_origin.y(), 0,
      base::TimeTicks(), ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_END));

  // Drag up on the app grid when on page 1, this should move the AppsGridView
  // but not the AppListView.
  apps_grid_view_->OnGestureEvent(&scroll_begin);
  EXPECT_TRUE(scroll_begin.handled());
  histogram_tester.ExpectTotalCount(
      "Apps.PaginationTransition.DragScroll.PresentationTime.ClamshellMode", 0);

  apps_grid_view_->OnGestureEvent(&scroll_update);
  EXPECT_TRUE(scroll_update.handled());
  ASSERT_FALSE(app_list_view_->is_in_drag());
  ASSERT_NE(0, GetPaginationModel()->transition().progress);
  histogram_tester.ExpectTotalCount(
      "Apps.PaginationTransition.DragScroll.PresentationTime.ClamshellMode", 1);
  histogram_tester.ExpectTotalCount(
      "Apps.PaginationTransition.DragScroll.PresentationTime.MaxLatency."
      "ClamshellMode",
      0);

  apps_grid_view_->OnGestureEvent(&scroll_end);

  histogram_tester.ExpectTotalCount(
      "Apps.PaginationTransition.DragScroll.PresentationTime.MaxLatency."
      "ClamshellMode",
      1);
}

TEST_F(AppsGridViewTest, CloseFolderByClickingBackground) {
  AppsContainerView* apps_container_view =
      contents_view_->apps_container_view();

  const size_t kTotalItems = GetAppListConfig().max_folder_items_per_page();
  model_->CreateAndPopulateFolderWithApps(kTotalItems);
  EXPECT_EQ(1u, model_->top_level_item_list()->item_count());
  EXPECT_EQ(AppListFolderItem::kItemType,
            model_->top_level_item_list()->item_at(0)->GetItemType());

  // Open the folder.
  test_api_->PressItemAt(0);
  EXPECT_TRUE(apps_container_view->IsInFolderView());

  // Simulate mouse press on folder background to close the folder.
  ui::MouseEvent event(ui::ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(),
                       ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON,
                       ui::EF_LEFT_MOUSE_BUTTON);
  apps_container_view->folder_background_view()->OnMouseEvent(&event);
  EXPECT_FALSE(apps_container_view->IsInFolderView());
}

// Tests that taps between apps within the AppsGridView does not result in the
// AppList closing.
TEST_P(AppsGridViewRTLTest, TapsBetweenAppsWontCloseAppList) {
  model_->PopulateApps(2);
  gfx::Point between_apps = GetItemRectOnCurrentPageAt(0, 0).right_center();
  gfx::Point empty_space = GetItemRectOnCurrentPageAt(0, 2).CenterPoint();

  // Taps between apps should be handled to prevent them from going into
  // app_list
  ui::GestureEvent tap_between = SimulateTap(between_apps);
  EXPECT_TRUE(tap_between.handled());

  // Taps outside of occupied tiles should not be handled, that they may close
  // the app_list
  ui::GestureEvent tap_outside = SimulateTap(empty_space);
  EXPECT_FALSE(tap_outside.handled());
}

TEST_F(AppsGridViewTest, PageResetAfterOpenFolder) {
  const size_t kTotalItems = GetAppListConfig().max_folder_pages() *
                             GetAppListConfig().max_folder_items_per_page();
  model_->CreateAndPopulateFolderWithApps(kTotalItems);
  EXPECT_EQ(1u, model_->top_level_item_list()->item_count());
  EXPECT_EQ(AppListFolderItem::kItemType,
            model_->top_level_item_list()->item_at(0)->GetItemType());

  // Open the folder. It should be at page 0.
  test_api_->PressItemAt(0);
  ash::PaginationModel* pagination_model =
      app_list_folder_view()->items_grid_view()->pagination_model();
  EXPECT_EQ(3, pagination_model->total_pages());
  EXPECT_EQ(0, pagination_model->selected_page());

  // Select page 2.
  pagination_model->SelectPage(2, false /* animate */);
  EXPECT_EQ(2, pagination_model->selected_page());

  // Close the folder and reopen it. It should be at page 0.
  app_list_folder_view()->CloseFolderPage();
  test_api_->PressItemAt(0);
  EXPECT_EQ(3, pagination_model->total_pages());
  EXPECT_EQ(0, pagination_model->selected_page());
}

TEST_F(AppsGridViewTest, FolderColsAndRows) {
  // Populate folders with different number of apps.
  model_->CreateAndPopulateFolderWithApps(2);
  model_->CreateAndPopulateFolderWithApps(5);
  model_->CreateAndPopulateFolderWithApps(9);
  model_->CreateAndPopulateFolderWithApps(15);
  model_->CreateAndPopulateFolderWithApps(17);

  // Check the number of cols and rows for each opened folder.
  AppsGridView* items_grid_view = app_list_folder_view()->items_grid_view();
  test_api_->PressItemAt(0);
  EXPECT_EQ(2, items_grid_view->view_model()->view_size());
  EXPECT_EQ(2, items_grid_view->cols());
  EXPECT_EQ(1, items_grid_view->rows_per_page());
  app_list_folder_view()->CloseFolderPage();

  test_api_->PressItemAt(1);
  EXPECT_EQ(5, items_grid_view->view_model()->view_size());
  EXPECT_EQ(3, items_grid_view->cols());
  EXPECT_EQ(2, items_grid_view->rows_per_page());
  app_list_folder_view()->CloseFolderPage();

  test_api_->PressItemAt(2);
  EXPECT_EQ(9, items_grid_view->view_model()->view_size());
  EXPECT_EQ(3, items_grid_view->cols());
  EXPECT_EQ(3, items_grid_view->rows_per_page());
  app_list_folder_view()->CloseFolderPage();

  test_api_->PressItemAt(3);
  EXPECT_EQ(15, items_grid_view->view_model()->view_size());
  EXPECT_EQ(4, items_grid_view->cols());
  EXPECT_EQ(4, items_grid_view->rows_per_page());
  app_list_folder_view()->CloseFolderPage();

  test_api_->PressItemAt(4);
  EXPECT_EQ(17, items_grid_view->view_model()->view_size());
  EXPECT_EQ(4, items_grid_view->cols());
  EXPECT_EQ(4, items_grid_view->rows_per_page());
  app_list_folder_view()->CloseFolderPage();
}

TEST_F(AppsGridViewTest, RemoveItemsInFolderShouldUpdateBounds) {
  // Populate two folders with different number of apps.
  model_->CreateAndPopulateFolderWithApps(2);
  AppListFolderItem* folder_2 = model_->CreateAndPopulateFolderWithApps(4);

  // Record the bounds of the folder view with 2 items in it.
  AppsGridView* items_grid_view = app_list_folder_view()->items_grid_view();
  test_api_->PressItemAt(0);
  EXPECT_TRUE(contents_view_->apps_container_view()->IsInFolderView());
  gfx::Rect one_row_folder_view = items_grid_view->GetBoundsInScreen();
  app_list_folder_view()->CloseFolderPage();

  // Record the bounds of the folder view with 4 items in it and keep the folder
  // view open for further testing.
  test_api_->PressItemAt(1);
  EXPECT_TRUE(contents_view_->apps_container_view()->IsInFolderView());
  gfx::Rect two_rows_folder_view = items_grid_view->GetBoundsInScreen();
  EXPECT_NE(one_row_folder_view.size(), two_rows_folder_view.size());

  // Remove one item from the folder with 4 items. The bound should stay the
  // same as there are still two rows in the folder view.
  model_->DeleteItem(folder_2->item_list()->item_at(0)->id());
  EXPECT_TRUE(contents_view_->apps_container_view()->IsInFolderView());
  items_grid_view->GetWidget()->LayoutRootViewIfNecessary();
  EXPECT_EQ(items_grid_view->GetBoundsInScreen().size(),
            two_rows_folder_view.size());

  // Remove another item from the folder. The bound should update and become the
  // folder view with one row.
  model_->DeleteItem(folder_2->item_list()->item_at(0)->id());
  EXPECT_TRUE(contents_view_->apps_container_view()->IsInFolderView());
  items_grid_view->GetWidget()->LayoutRootViewIfNecessary();
  EXPECT_EQ(items_grid_view->GetBoundsInScreen().size(),
            one_row_folder_view.size());
}

TEST_F(AppsGridViewTest, AddItemsToFolderShouldUpdateBounds) {
  // Populate two folders with different number of apps.
  AppListFolderItem* folder_1 = model_->CreateAndPopulateFolderWithApps(2);
  model_->CreateAndPopulateFolderWithApps(4);

  // Record the bounds of the folder view with 4 items in it.
  AppsGridView* items_grid_view = app_list_folder_view()->items_grid_view();
  test_api_->PressItemAt(1);
  EXPECT_TRUE(contents_view_->apps_container_view()->IsInFolderView());
  gfx::Rect two_rows_folder_view = items_grid_view->GetBoundsInScreen();
  app_list_folder_view()->CloseFolderPage();

  // Record the bounds of the folder view with 2 items in it and keep the folder
  // view open for further testing.
  test_api_->PressItemAt(0);
  EXPECT_TRUE(contents_view_->apps_container_view()->IsInFolderView());
  gfx::Rect one_row_folder_view = items_grid_view->GetBoundsInScreen();
  EXPECT_NE(one_row_folder_view.size(), two_rows_folder_view.size());

  // Add an item to the folder so that there are two rows in the folder view.
  model_->AddItemToFolder(model_->CreateItem("Extra 1"), folder_1->id());
  EXPECT_TRUE(contents_view_->apps_container_view()->IsInFolderView());
  items_grid_view->GetWidget()->LayoutRootViewIfNecessary();
  EXPECT_EQ(items_grid_view->GetBoundsInScreen().size(),
            two_rows_folder_view.size());
  app_list_folder_view()->CloseFolderPage();

  // Create a folder with a full page of apps. Add an item to the folder should
  // not change the size of the folder view.
  AppListFolderItem* folder_full = model_->CreateAndPopulateFolderWithApps(
      GetAppListConfig().max_folder_items_per_page());
  test_api_->PressItemAt(2);
  EXPECT_TRUE(contents_view_->apps_container_view()->IsInFolderView());
  gfx::Rect full_folder_view = items_grid_view->GetBoundsInScreen();

  model_->AddItemToFolder(model_->CreateItem("Extra 2"), folder_full->id());
  EXPECT_EQ(items_grid_view->GetBoundsInScreen().size(),
            full_folder_view.size());
  app_list_folder_view()->CloseFolderPage();
}

TEST_P(AppsGridViewRTLTest, ScrollDownShouldNotExitFolder) {
  const size_t kTotalItems = GetAppListConfig().max_folder_items_per_page();
  model_->CreateAndPopulateFolderWithApps(kTotalItems);
  EXPECT_EQ(1u, model_->top_level_item_list()->item_count());
  EXPECT_EQ(AppListFolderItem::kItemType,
            model_->top_level_item_list()->item_at(0)->GetItemType());

  // Open the folder.
  test_api_->PressItemAt(0);
  EXPECT_TRUE(contents_view_->apps_container_view()->IsInFolderView());

  AppsGridView* items_grid_view = app_list_folder_view()->items_grid_view();
  gfx::Point apps_grid_view_origin =
      items_grid_view->GetBoundsInScreen().origin();
  ui::GestureEvent scroll_begin(
      apps_grid_view_origin.x(), apps_grid_view_origin.y(), 0,
      base::TimeTicks(),
      ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_BEGIN, 0, 1));
  ui::GestureEvent scroll_update(
      apps_grid_view_origin.x(), apps_grid_view_origin.y(), 0,
      base::TimeTicks(),
      ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_UPDATE, 0, 10));

  // Drag down on the items grid, this should be handled by items grid view and
  // the folder should not be closed.
  items_grid_view->OnGestureEvent(&scroll_begin);
  EXPECT_TRUE(scroll_begin.handled());
  EXPECT_TRUE(contents_view_->apps_container_view()->IsInFolderView());
}

// Tests that an app icon is selected when a menu is shown by click.
TEST_F(AppsGridViewTest, AppIconSelectedWhenMenuIsShown) {
  model_->PopulateApps(1);
  ASSERT_EQ(1u, model_->top_level_item_list()->item_count());
  AppListItemView* app = GetItemViewInTopLevelGrid(0);
  EXPECT_FALSE(apps_grid_view_->IsSelectedView(app));

  // Send a mouse event which would show a context menu.
  ui::MouseEvent press_event(ui::ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(),
                             ui::EventTimeForNow(), ui::EF_RIGHT_MOUSE_BUTTON,
                             ui::EF_RIGHT_MOUSE_BUTTON);

  // Use a views::View* to expose OnMouseEvent.
  views::View* const view = app;
  view->OnMouseEvent(&press_event);
  EXPECT_TRUE(apps_grid_view_->IsSelectedView(app));

  ui::MouseEvent release_event(
      ui::ET_MOUSE_RELEASED, gfx::Point(), gfx::Point(), ui::EventTimeForNow(),
      ui::EF_RIGHT_MOUSE_BUTTON, ui::EF_RIGHT_MOUSE_BUTTON);
  view->OnMouseEvent(&release_event);
  EXPECT_TRUE(apps_grid_view_->IsSelectedView(app));

  // Cancel the menu, |app| should no longer be selected.
  app->CancelContextMenu();
  EXPECT_FALSE(apps_grid_view_->IsSelectedView(app));
}

// Tests that the context menu for app item appears at the right position.
TEST_P(AppsGridViewRTLTest, MenuAtRightPosition) {
  const size_t kItemsInPage =
      apps_grid_view_->cols() * apps_grid_view_->rows_per_page();
  const size_t kPages = 2;
  model_->PopulateApps(kItemsInPage * kPages);

  auto* root = apps_grid_view_->GetWidget()->GetNativeWindow()->GetRootWindow();
  gfx::Rect root_bounds = root->GetBoundsInScreen();

  std::vector<int> pages_to_check = {1, 0};
  for (int i : pages_to_check) {
    GetPaginationModel()->SelectPage(i, /*animate=*/false);

    for (size_t j = 0; j < kItemsInPage; ++j) {
      const size_t idx = kItemsInPage * i + j;
      AppListItemView* item_view = GetItemViewInTopLevelGrid(idx);

      // Send a mouse event which would show a context menu.
      ui::MouseEvent press_event(ui::ET_MOUSE_PRESSED, gfx::Point(),
                                 gfx::Point(), ui::EventTimeForNow(),
                                 ui::EF_RIGHT_MOUSE_BUTTON,
                                 ui::EF_RIGHT_MOUSE_BUTTON);
      static_cast<views::View*>(item_view)->OnMouseEvent(&press_event);

      ui::MouseEvent release_event(ui::ET_MOUSE_RELEASED, gfx::Point(),
                                   gfx::Point(), ui::EventTimeForNow(),
                                   ui::EF_RIGHT_MOUSE_BUTTON,
                                   ui::EF_RIGHT_MOUSE_BUTTON);
      static_cast<views::View*>(item_view)->OnMouseEvent(&release_event);

      // Make sure that the menu is drawn on screen.
      auto* menu_window = FindMenuWindow(root);
      gfx::Rect menu_bounds = menu_window->GetBoundsInScreen();
      EXPECT_TRUE(root_bounds.Contains(menu_bounds))
          << "menu bounds for " << idx << "-th item " << menu_bounds.ToString()
          << " is outside of the screen bounds " << root_bounds.ToString();

      // CancelContextMenu doesn't remove the menu window immediately, so wait
      // for its actual deletion.
      WindowDeletionWaiter waiter(menu_window);
      item_view->CancelContextMenu();
      waiter.Wait();
    }
  }
}

TEST_F(AppsGridViewTest, ItemViewsDontHaveLayer) {
  size_t kTotalItems = 3;
  model_->PopulateApps(kTotalItems);

  // Normally individual item-view does not have a layer.
  for (size_t i = 0; i < model_->top_level_item_list()->item_count(); ++i)
    EXPECT_FALSE(GetItemViewInTopLevelGrid(i)->layer());
}

TEST_P(AppsGridViewDragAndDropTest, ItemViewsHaveLayerDuringDrag) {
  size_t kTotalItems = 3;
  model_->PopulateApps(kTotalItems);
  gfx::Point from = GetItemRectOnCurrentPageAt(0, 1).CenterPoint();
  InitiateDrag(AppsGridView::MOUSE, from, apps_grid_view_);

  // Dragging item_1 over item_0 creates a folder.
  gfx::Point to = GetItemRectOnCurrentPageAt(0, 0).CenterPoint();
  UpdateDrag(AppsGridView::MOUSE, to, apps_grid_view_, 10 /*steps*/);

  // Each item view has its own layer during the drag.
  for (size_t i = 0; i < model_->top_level_item_list()->item_count(); ++i)
    EXPECT_TRUE(GetItemViewInTopLevelGrid(i)->layer());

  EndDrag(apps_grid_view_, false /*cancel*/);
}

TEST_P(AppsGridViewDragAndDropTest, ItemViewsDontHaveLayerAfterDrag) {
  size_t kTotalItems = 3;
  model_->PopulateApps(kTotalItems);
  gfx::Point from = GetItemRectOnCurrentPageAt(0, 1).CenterPoint();
  InitiateDrag(AppsGridView::MOUSE, from, apps_grid_view_);

  // Dragging item_1 over item_0 creates a folder.
  gfx::Point to = GetItemRectOnCurrentPageAt(0, 0).CenterPoint();
  UpdateDrag(AppsGridView::MOUSE, to, apps_grid_view_, 10 /*steps*/);
  EndDrag(apps_grid_view_, false /*cancel*/);
  test_api_->WaitForItemMoveAnimationDone();

  // The layer should be destroyed after the dragging.
  for (size_t i = 0; i < model_->top_level_item_list()->item_count(); ++i)
    EXPECT_FALSE(GetItemViewInTopLevelGrid(i)->layer());
}

TEST_P(AppsGridViewDragAndDropTest, MouseDragItemIntoFolder) {
  size_t kTotalItems = 3;
  model_->PopulateApps(kTotalItems);
  gfx::Point from = GetItemRectOnCurrentPageAt(0, 1).CenterPoint();
  InitiateDrag(AppsGridView::MOUSE, from, apps_grid_view_);

  // Dragging item_1 over item_0 creates a folder.
  gfx::Point to = GetItemRectOnCurrentPageAt(0, 0).CenterPoint();
  UpdateDrag(AppsGridView::MOUSE, to, apps_grid_view_, 10 /*steps*/);
  EndDrag(apps_grid_view_, false /*cancel*/);
  test_api_->WaitForItemMoveAnimationDone();
  test_api_->LayoutToIdealBounds();

  EXPECT_EQ(kTotalItems - 1, model_->top_level_item_list()->item_count());
  EXPECT_EQ(AppListFolderItem::kItemType,
            model_->top_level_item_list()->item_at(0)->GetItemType());
  AppListFolderItem* folder_item = static_cast<AppListFolderItem*>(
      model_->top_level_item_list()->item_at(0));
  EXPECT_EQ(2u, folder_item->ChildItemCount());
  AppListItem* item_0 = model_->FindItem("Item 0");
  EXPECT_TRUE(item_0->IsInFolder());
  EXPECT_EQ(folder_item->id(), item_0->folder_id());
  AppListItem* item_1 = model_->FindItem("Item 1");
  EXPECT_TRUE(item_1->IsInFolder());
  EXPECT_EQ(folder_item->id(), item_1->folder_id());
  std::string expected_items = folder_item->id() + ",Item 2";
  EXPECT_EQ(expected_items, model_->GetModelContent());
}

TEST_P(AppsGridViewDragAndDropTest, MouseDragSecondItemIntoFolder) {
  AppListFolderItem* folder_item = model_->CreateAndPopulateFolderWithApps(2);
  model_->PopulateApps(1);
  gfx::Point from = GetItemRectOnCurrentPageAt(0, 1).CenterPoint();
  InitiateDrag(AppsGridView::MOUSE, from, apps_grid_view_);

  // Dragging item_2 to the folder adds Item_2 to the folder.
  gfx::Point to = GetItemRectOnCurrentPageAt(0, 0).CenterPoint();
  UpdateDrag(AppsGridView::MOUSE, to, apps_grid_view_, 10 /*steps*/);
  EndDrag(apps_grid_view_, false /*cancel*/);
  test_api_->WaitForItemMoveAnimationDone();
  test_api_->LayoutToIdealBounds();

  EXPECT_EQ(1u, model_->top_level_item_list()->item_count());
  EXPECT_EQ(folder_item->id(), model_->GetModelContent());
  EXPECT_EQ(3u, folder_item->ChildItemCount());
  AppListItem* item_0 = model_->FindItem("Item 0");
  EXPECT_TRUE(item_0->IsInFolder());
  EXPECT_EQ(folder_item->id(), item_0->folder_id());
  AppListItem* item_1 = model_->FindItem("Item 1");
  EXPECT_TRUE(item_1->IsInFolder());
  EXPECT_EQ(folder_item->id(), item_1->folder_id());
  AppListItem* item_2 = model_->FindItem("Item 2");
  EXPECT_TRUE(item_2->IsInFolder());
  EXPECT_EQ(folder_item->id(), item_2->folder_id());
}

TEST_F(AppsGridViewTest, CheckFolderWithMultiplePagesContents) {
  // Creates a folder item.
  const size_t kTotalItems = GetAppListConfig().max_folder_items_per_page();
  AppListFolderItem* folder_item =
      model_->CreateAndPopulateFolderWithApps(kTotalItems);

  // Open the folder and check it's contents.
  test_api_->Update();
  test_api_->PressItemAt(0);

  EXPECT_EQ(1u, model_->top_level_item_list()->item_count());
  EXPECT_EQ(AppListFolderItem::kItemType,
            model_->top_level_item_list()->item_at(0)->GetItemType());
  EXPECT_EQ(kTotalItems, folder_item->ChildItemCount());
  EXPECT_EQ(4, folder_apps_grid_view()->cols());
  EXPECT_EQ(4, folder_apps_grid_view()->rows_per_page());
  ash::PaginationModel* folder_pagination_model =
      folder_apps_grid_view()->pagination_model();
  EXPECT_EQ(1, folder_pagination_model->total_pages());
  EXPECT_EQ(0, folder_pagination_model->selected_page());
  EXPECT_TRUE(folder_apps_grid_view()->IsInFolder());
}

TEST_P(AppsGridViewDragAndDropTest, MouseDragItemOutOfFolderFirstPage) {
  // Creates a folder item.
  const size_t kTotalItems = GetAppListConfig().max_folder_items_per_page();
  AppListFolderItem* folder_item =
      model_->CreateAndPopulateFolderWithApps(kTotalItems);
  test_api_->Update();
  test_api_->PressItemAt(0);
  AppsGridViewTestApi folder_grid_test_api(folder_apps_grid_view());
  gfx::Point from =
      folder_grid_test_api.GetItemTileRectOnCurrentPageAt(0, 0).CenterPoint();
  // Calculate the coordinates for the drop point. Note that we we are dropping
  // into the app list view not the folder view. The (0,1) spot is empty.
  gfx::Point drop_point = GetItemRectOnCurrentPageAt(0, 1).CenterPoint();
  drop_point.set_x(apps_grid_view_->GetMirroredXInView(drop_point.x()));

  // Drag the first folder child out of the folder.
  AppListItemView* drag_view =
      InitiateDrag(AppsGridView::MOUSE, from, folder_apps_grid_view());
  gfx::Point empty_space =
      app_list_folder_view()->GetLocalBounds().bottom_center() +
      gfx::Vector2d(0, drag_view->height()
                    /*padding to completely exit folder view*/);
  UpdateDrag(AppsGridView::MOUSE, empty_space, folder_apps_grid_view(),
             10 /*steps*/);
  // Fire the reparent timer that should be started when an item is dragged out
  // of folder bounds.
  ASSERT_TRUE(folder_apps_grid_view()->FireFolderItemReparentTimerForTest());
  views::View::ConvertPointToTarget(apps_grid_view_, folder_apps_grid_view(),
                                    &drop_point);
  UpdateDrag(AppsGridView::MOUSE, drop_point, folder_apps_grid_view(),
             5 /*steps*/);
  EndDrag(folder_apps_grid_view(), false /*cancel*/);

  AppListItem* item_0 = model_->FindItem("Item 0");
  AppListItem* item_1 = model_->FindItem("Item 1");
  EXPECT_FALSE(item_0->IsInFolder());
  EXPECT_TRUE(item_1->IsInFolder());
  EXPECT_EQ(folder_item->id(), item_1->folder_id());
  EXPECT_EQ(std::string(folder_item->id() + ",Item 0"),
            model_->GetModelContent());
  EXPECT_EQ(kTotalItems - 1, folder_item->ChildItemCount());
}

TEST_F(AppsGridViewTest, SwitchPageFolderItem) {
  // Creates a folder item with enough views to have a second page.
  const size_t kTotalItems = GetAppListConfig().max_folder_items_per_page() + 1;
  model_->CreateAndPopulateFolderWithApps(kTotalItems);

  // Switch to second page and check it's contents.
  test_api_->Update();
  test_api_->PressItemAt(0);
  AnimateFolderViewPageFlip(1);

  EXPECT_EQ(1, folder_apps_grid_view()->pagination_model()->selected_page());
  EXPECT_EQ(4, folder_apps_grid_view()->cols());
  EXPECT_EQ(4, folder_apps_grid_view()->rows_per_page());
  EXPECT_TRUE(folder_apps_grid_view()->IsInFolder());
}

TEST_P(AppsGridViewDragAndDropTest, MouseDragItemOutOfFolderSecondPage) {
  // Creates a folder item with enough views to have a second page.
  const size_t kTotalItems = GetAppListConfig().max_folder_items_per_page() + 1;
  AppListFolderItem* folder_item =
      model_->CreateAndPopulateFolderWithApps(kTotalItems);
  test_api_->Update();
  test_api_->PressItemAt(0);
  AppsGridViewTestApi folder_grid_test_api(folder_apps_grid_view());
  // Switch to second page.
  AnimateFolderViewPageFlip(1);
  gfx::Point from =
      folder_grid_test_api.GetItemTileRectOnCurrentPageAt(0, 0).CenterPoint();
  // Calculate the coordinates for the drop point. Note that we we are dropping
  // into the app list view not the folder view. The (0,1) spot is empty.
  gfx::Point drop_point = GetItemRectOnCurrentPageAt(0, 1).CenterPoint();

  // Drag the first folder child on the second page out of the folder.
  AppListItemView* drag_view =
      InitiateDrag(AppsGridView::MOUSE, from, folder_apps_grid_view());
  // Calculate the target destination for our drag and update the drag to that
  // location.
  gfx::Point empty_space =
      app_list_folder_view()->GetLocalBounds().bottom_center() +
      gfx::Vector2d(0, drag_view->height()
                    /*padding to completely exit folder view*/);
  UpdateDrag(AppsGridView::MOUSE, empty_space, folder_apps_grid_view(),
             10 /*steps*/);
  // Fire the reparent timer that should be started when an item is dragged out
  // of folder bounds.
  ASSERT_TRUE(folder_apps_grid_view()->FireFolderItemReparentTimerForTest());
  drop_point.set_x(apps_grid_view_->GetMirroredXInView(drop_point.x()));
  views::View::ConvertPointToTarget(apps_grid_view_, folder_apps_grid_view(),
                                    &drop_point);
  UpdateDrag(AppsGridView::MOUSE, drop_point, folder_apps_grid_view(),
             5 /*steps*/);
  // End the drag and assert that the item has been dragged out of the folder
  // and the app list's grid view has been updated accordingly.
  EndDrag(folder_apps_grid_view(), false /*cancel*/);

  AppListItem* item_0 = model_->FindItem("Item 0");
  AppListItem* item_16 = model_->FindItem("Item 16");
  EXPECT_TRUE(item_0->IsInFolder());
  EXPECT_FALSE(item_16->IsInFolder());
  EXPECT_EQ(folder_item->id(), item_0->folder_id());
  EXPECT_EQ(std::string(folder_item->id() + ",Item 16"),
            model_->GetModelContent());
  EXPECT_EQ(kTotalItems - 1, folder_item->ChildItemCount());
}

TEST_P(AppsGridViewDragAndDropTestNoCardifiedState,
       MouseDropItemFromFolderSecondPage) {
  // Creates a folder item with enough views to have a second page.
  const size_t kTotalItems = GetAppListConfig().max_folder_items_per_page() + 1;
  AppListFolderItem* folder_item =
      model_->CreateAndPopulateFolderWithApps(kTotalItems);
  test_api_->Update();
  test_api_->PressItemAt(0);
  ASSERT_TRUE(folder_apps_grid_view()->IsInFolder());
  // Switch to second page.
  AnimateFolderViewPageFlip(1);
  // Fill the rest of the root grid view with new app list items. Leave 1 slot
  // open so dropping an item from a folder to the root level apps grid does not
  // cause a page overflow.
  model_->PopulateApps(GetTilesPerPage() - 2);
  AppsGridViewTestApi folder_grid_test_api(folder_apps_grid_view());
  gfx::Point from =
      folder_grid_test_api.GetItemTileRectOnCurrentPageAt(0, 0).CenterPoint();

  // Drag the first folder child on the second page out of the folder.
  AppListItemView* drag_view =
      InitiateDrag(AppsGridView::MOUSE, from, folder_apps_grid_view());
  // Calculate the target destination for our drag and update the drag to that
  // location.
  gfx::Point empty_space =
      app_list_folder_view()->GetLocalBounds().bottom_center() +
      gfx::Vector2d(0, drag_view->height()
                    /*padding to completely exit folder view*/);
  UpdateDrag(AppsGridView::MOUSE, empty_space, folder_apps_grid_view(),
             10 /*steps*/);
  // Fire the reparent timer that should be started when an item is dragged out
  // of folder bounds.
  ASSERT_TRUE(folder_apps_grid_view()->FireFolderItemReparentTimerForTest());
  // Calculate the coordinates for the drop point. Note that we we are dropping
  // into the app list view not the folder view. We will drop between the folder
  // and the rest of the app list items in the root level apps grid view.
  gfx::Point drop_point = is_rtl_
                              ? GetItemRectOnCurrentPageAt(0, 2).right_center()
                              : GetItemRectOnCurrentPageAt(0, 0).right_center();
  drop_point.set_x(apps_grid_view_->GetMirroredXInView(drop_point.x()));
  views::View::ConvertPointToTarget(apps_grid_view_, folder_apps_grid_view(),
                                    &drop_point);
  UpdateDrag(AppsGridView::MOUSE, drop_point, folder_apps_grid_view(),
             5 /*steps*/);
  // End the drag and assert that the item has been dragged out of the folder
  // and the app list's grid view has been updated accordingly.
  EndDrag(folder_apps_grid_view(), false /*cancel*/);

  AppListItem* item_0 = model_->FindItem("Item 0");
  AppListItem* item_16 = model_->FindItem("Item 16");
  EXPECT_TRUE(item_0->IsInFolder());
  EXPECT_FALSE(item_16->IsInFolder());
  EXPECT_EQ(folder_item->id(), item_0->folder_id());
  EXPECT_EQ(std::string(folder_item->id() +
                        ",Item 16,Item 17,Item 18,Item 19,Item 20,Item 21,Item "
                        "22,Item 23,Item 24,Item 25,Item 26,Item 27,Item "
                        "28,Item 29,Item 30,Item 31,Item 32,Item 33,Item 34"),
            model_->GetModelContent());
  EXPECT_EQ(kTotalItems - 1, folder_item->ChildItemCount());
}

TEST_P(AppsGridViewDragAndDropTest, MouseDragMaxItemsInFolder) {
  // Create and add a folder with |kMaxFolderItemsFullscreen - 1| items.
  const size_t kMaxItems = GetAppListConfig().max_folder_items_per_page() *
                           GetAppListConfig().max_folder_pages();
  const size_t kTotalItems = kMaxItems - 1;
  AppListFolderItem* folder_item =
      model_->CreateAndPopulateFolderWithApps(kTotalItems);
  // Create and add another item.
  model_->PopulateAppWithId(kTotalItems);
  gfx::Point from = GetItemRectOnCurrentPageAt(0, 1).CenterPoint();
  InitiateDrag(AppsGridView::MOUSE, from, apps_grid_view_);

  // Dragging one item into the folder, the folder should accept the item.
  gfx::Point to = GetItemRectOnCurrentPageAt(0, 0).CenterPoint();
  UpdateDrag(AppsGridView::MOUSE, to, apps_grid_view_, 10 /*steps*/);
  EndDrag(apps_grid_view_, false /*cancel*/);
  test_api_->LayoutToIdealBounds();

  EXPECT_EQ(1u, model_->top_level_item_list()->item_count());
  EXPECT_EQ(folder_item->id(), model_->top_level_item_list()->item_at(0)->id());
  EXPECT_EQ(kMaxItems, folder_item->ChildItemCount());
}

TEST_P(AppsGridViewDragAndDropTest, MouseDragExceedMaxItemsInFolder) {
  // Create and add a folder with |kMaxFolderItemsFullscreen - 1| items.
  const size_t kMaxItems = GetAppListConfig().max_folder_items_per_page() *
                           GetAppListConfig().max_folder_pages();
  AppListFolderItem* folder_item =
      model_->CreateAndPopulateFolderWithApps(kMaxItems);
  // Create and add another 2 item.
  model_->PopulateAppWithId(kMaxItems + 1);
  gfx::Point from = GetItemRectOnCurrentPageAt(0, 1).CenterPoint();
  InitiateDrag(AppsGridView::MOUSE, from, apps_grid_view_);

  // Dragging the last item over the folder, the folder won't accept the new
  // item.
  gfx::Point to = GetItemRectOnCurrentPageAt(0, 0).CenterPoint();
  UpdateDrag(AppsGridView::MOUSE, to, apps_grid_view_, 10 /*steps*/);
  EndDrag(apps_grid_view_, false /*cancel*/);
  test_api_->LayoutToIdealBounds();

  EXPECT_EQ(2u, model_->top_level_item_list()->item_count());
  EXPECT_EQ(kMaxItems, folder_item->ChildItemCount());
}

TEST_P(AppsGridViewDragAndDropTest, MouseDragMovement) {
  // Create and add a folder with |kMaxFolderItemsFullscreen| in it.
  const size_t kMaxItems = GetAppListConfig().max_folder_items_per_page() *
                           GetAppListConfig().max_folder_pages();
  model_->CreateAndPopulateFolderWithApps(kMaxItems);
  // Create and add another item.
  model_->PopulateAppWithId(kMaxItems);
  AppListItemView* folder_view =
      GetItemViewForPoint(GetItemRectOnCurrentPageAt(0, 0).CenterPoint());
  // Drag the new item to the left so that the grid reorders.
  gfx::Point from = GetItemRectOnCurrentPageAt(0, 1).CenterPoint();
  InitiateDrag(AppsGridView::MOUSE, from, apps_grid_view_);

  gfx::Point to = GetItemRectOnCurrentPageAt(0, 0).bottom_left();
  to.Offset(0, -1);  // Get a point inside the rect.
  UpdateDrag(AppsGridView::MOUSE, to, apps_grid_view_, 10 /*steps*/);
  test_api_->LayoutToIdealBounds();

  // The grid now looks like | blank | folder |.
  EXPECT_EQ(nullptr, GetItemViewForPoint(
                         GetItemRectOnCurrentPageAt(0, 0).CenterPoint()));
  EXPECT_EQ(folder_view, GetItemViewForPoint(
                             GetItemRectOnCurrentPageAt(0, 1).CenterPoint()));

  EndDrag(apps_grid_view_, false /*cancel*/);
}

// Check that moving items around doesn't allow a drop to happen into a full
// folder.
TEST_P(AppsGridViewDragAndDropTest, MouseDragMaxItemsInFolderWithMovement) {
  // Create and add a folder with |kMaxFolderItemsFullscreen| in it.
  const size_t kMaxItems = GetAppListConfig().max_folder_items_per_page() *
                           GetAppListConfig().max_folder_pages();
  model_->CreateAndPopulateFolderWithApps(kMaxItems);
  AppListFolderItem* folder_item = static_cast<AppListFolderItem*>(
      model_->top_level_item_list()->item_at(0));
  // Create and add another item.
  model_->PopulateAppWithId(kMaxItems);
  // Drag the new item to the left so that the grid reorders.
  gfx::Point from = GetItemRectOnCurrentPageAt(0, 1).CenterPoint();
  AppListItemView* dragged_view =
      InitiateDrag(AppsGridView::MOUSE, from, apps_grid_view_);

  gfx::Point to = GetItemRectOnCurrentPageAt(0, 0).bottom_left();
  to.Offset(0, -1);  // Get a point inside the rect.
  UpdateDrag(AppsGridView::MOUSE, to, apps_grid_view_, 10 /*steps*/);
  gfx::Point folder_in_second_slot =
      GetItemRectOnCurrentPageAt(0, 1).CenterPoint();
  gfx::Point translated_destination = gfx::PointAtOffsetFromOrigin(
      folder_in_second_slot - dragged_view->origin());
  ui::MouseEvent drag_event(ui::ET_MOUSE_DRAGGED, translated_destination,
                            folder_in_second_slot, ui::EventTimeForNow(), 0, 0);
  apps_grid_view_->UpdateDragFromItem(AppsGridView::MOUSE, drag_event);
  EndDrag(apps_grid_view_, false /*cancel*/);

  // The item should not have moved into the folder.
  EXPECT_EQ(2u, model_->top_level_item_list()->item_count());
  EXPECT_EQ(kMaxItems, folder_item->ChildItemCount());
  test_api_->LayoutToIdealBounds();
}

// Dragging an item towards its neighbours should not reorder until the drag is
// past the folder drop point.
TEST_P(AppsGridViewDragAndDropTest, MouseDragItemReorderBeforeFolderDropPoint) {
  model_->PopulateApps(2);
  contents_view_->apps_container_view()->Layout();
  gfx::Point from = GetItemRectOnCurrentPageAt(0, 1).CenterPoint();
  InitiateDrag(AppsGridView::MOUSE, from, apps_grid_view_);
  // Item's starting point has to be recelculated because drag state may change
  // item coordinates within the apps grid.
  from = GetItemRectOnCurrentPageAt(0, 1).CenterPoint();
  int half_tile_width = (GetItemRectOnCurrentPageAt(0, 1).x() -
                         GetItemRectOnCurrentPageAt(0, 0).x()) /
                        2;
  gfx::Vector2d drag_vector(-half_tile_width - 4, 0);

  // Drag left but stop before the folder dropping circle.
  UpdateDrag(AppsGridView::MOUSE, from + drag_vector, apps_grid_view_,
             10 /*steps*/);
  EndDrag(apps_grid_view_, false /*cancel*/);

  EXPECT_EQ(std::string("Item 0,Item 1"), model_->GetModelContent());
  TestAppListItemViewIndice();
}

TEST_P(AppsGridViewDragAndDropTest, MouseDragItemReorderAfterFolderDropPoint) {
  model_->PopulateApps(2);
  contents_view_->apps_container_view()->Layout();
  gfx::Point from = GetItemRectOnCurrentPageAt(0, 1).CenterPoint();
  InitiateDrag(AppsGridView::MOUSE, from, apps_grid_view_);
  // Item's starting point has to be recelculated because drag state may change
  // item coordinates within the apps grid.
  from = GetItemRectOnCurrentPageAt(0, 1).CenterPoint();
  int half_tile_width = (GetItemRectOnCurrentPageAt(0, 1).x() -
                         GetItemRectOnCurrentPageAt(0, 0).x()) /
                        2;
  gfx::Vector2d drag_vector(
      -2 * half_tile_width -
          GetAppListConfig().folder_dropping_circle_radius() - 4,
      0);

  // Drag left, past the folder dropping circle.
  UpdateDrag(AppsGridView::MOUSE, from + drag_vector, apps_grid_view_,
             10 /*steps*/);
  EndDrag(apps_grid_view_, false /*cancel*/);

  EXPECT_EQ(std::string("Item 1,Item 0"), model_->GetModelContent());
  TestAppListItemViewIndice();
}

TEST_P(AppsGridViewDragAndDropTest, MouseDragItemReorderDragDownOneRow) {
  // The default layout is 5x4, populate 7 apps so that we have second row to
  // test dragging item to second row.
  model_->PopulateApps(7);
  contents_view_->apps_container_view()->Layout();
  gfx::Point from = GetItemRectOnCurrentPageAt(0, 1).CenterPoint();
  // Item's starting point has to be recelculated because drag state may change
  // item coordinates within the apps grid.
  InitiateDrag(AppsGridView::MOUSE, from, apps_grid_view_);
  from = GetItemRectOnCurrentPageAt(0, 1).CenterPoint();
  int half_tile_width = (GetItemRectOnCurrentPageAt(0, 1).x() -
                         GetItemRectOnCurrentPageAt(0, 0).x()) /
                        2;
  int tile_height = GetItemRectOnCurrentPageAt(1, 0).y() -
                    GetItemRectOnCurrentPageAt(0, 0).y();
  gfx::Vector2d drag_vector(-half_tile_width, tile_height);

  // Drag down, between apps 5 and 6. The gap should open up, making space for
  // app 1 in the bottom left.
  UpdateDrag(AppsGridView::MOUSE, from + drag_vector, apps_grid_view_,
             10 /*steps*/);
  EndDrag(apps_grid_view_, false /*cancel*/);

  EXPECT_EQ(std::string("Item 0,Item 2,Item 3,Item 4,Item 5,Item 1,Item 6"),
            model_->GetModelContent());
  TestAppListItemViewIndice();
}

TEST_P(AppsGridViewDragAndDropTest, MouseDragItemReorderDragUpOneRow) {
  // The default layout is 5x4, populate 7 apps so that we have second row to
  // test dragging item to second row.
  model_->PopulateApps(7);
  contents_view_->apps_container_view()->Layout();
  gfx::Point from = GetItemRectOnCurrentPageAt(1, 0).CenterPoint();
  InitiateDrag(AppsGridView::MOUSE, from, apps_grid_view_);
  // Item's starting point has to be recelculated because drag state may change
  // item coordinates within the apps grid.
  from = GetItemRectOnCurrentPageAt(1, 0).CenterPoint();
  int half_tile_width = (GetItemRectOnCurrentPageAt(0, 1).x() -
                         GetItemRectOnCurrentPageAt(0, 0).x()) /
                        2;
  int tile_height = GetItemRectOnCurrentPageAt(1, 0).y() -
                    GetItemRectOnCurrentPageAt(0, 0).y();
  gfx::Vector2d drag_vector(half_tile_width, -tile_height);

  // Drag up, between apps 0 and 2. The gap should open up, making space for app
  // 1 in the top right.
  UpdateDrag(AppsGridView::MOUSE, from + drag_vector, apps_grid_view_,
             10 /*steps*/);
  EndDrag(apps_grid_view_, false /*cancel*/);
  test_api_->LayoutToIdealBounds();

  EXPECT_EQ(std::string("Item 0,Item 5,Item 1,Item 2,Item 3,Item 4,Item 6"),
            model_->GetModelContent());
  TestAppListItemViewIndice();
}

TEST_P(AppsGridViewDragAndDropTest, MouseDragItemReorderDragPastLastApp) {
  // The default layout is 5x4, populate 7 apps so that we have second row to
  // test dragging item to second row.
  model_->PopulateApps(7);
  contents_view_->apps_container_view()->Layout();
  gfx::Point from = GetItemRectOnCurrentPageAt(0, 1).CenterPoint();
  InitiateDrag(AppsGridView::MOUSE, from, apps_grid_view_);
  // Item's starting point has to be recelculated because drag state may change
  // item coordinates within the apps grid.
  from = GetItemRectOnCurrentPageAt(0, 1).CenterPoint();
  int half_tile_width = (GetItemRectOnCurrentPageAt(0, 1).x() -
                         GetItemRectOnCurrentPageAt(0, 0).x()) /
                        2;
  int tile_height = GetItemRectOnCurrentPageAt(1, 0).y() -
                    GetItemRectOnCurrentPageAt(0, 0).y();
  gfx::Vector2d drag_vector(half_tile_width, 2 * tile_height);

  // Drag up, between apps 0 and 2. The gap should open up, making space for app
  // 1 in the top right.
  UpdateDrag(AppsGridView::MOUSE, from + drag_vector, apps_grid_view_,
             10 /*steps*/);
  EndDrag(apps_grid_view_, false /*cancel*/);

  EXPECT_EQ(std::string("Item 0,Item 2,Item 3,Item 4,Item 5,Item 6,Item 1"),
            model_->GetModelContent());
  TestAppListItemViewIndice();
}

// Dragging folder over item_2 should leads to re-ordering these two items.
TEST_P(AppsGridViewDragAndDropTest, MouseDragFolderOverItemReorder) {
  size_t kTotalItems = 2;
  AppListFolderItem* folder_item =
      model_->CreateAndPopulateFolderWithApps(kTotalItems);
  model_->PopulateAppWithId(kTotalItems);
  gfx::Point from = GetItemRectOnCurrentPageAt(0, 0).CenterPoint();
  InitiateDrag(AppsGridView::MOUSE, from, apps_grid_view_);
  gfx::Point to = GetItemRectOnCurrentPageAt(0, 1).CenterPoint();

  UpdateDrag(AppsGridView::MOUSE, to, apps_grid_view_);
  EndDrag(apps_grid_view_, false /*cancel*/);
  test_api_->LayoutToIdealBounds();

  EXPECT_EQ(2u, model_->top_level_item_list()->item_count());
  EXPECT_EQ("Item 2", model_->top_level_item_list()->item_at(0)->id());
  EXPECT_EQ(folder_item->id(), model_->top_level_item_list()->item_at(1)->id());
  TestAppListItemViewIndice();
}

// Canceling drag should keep existing order.
TEST_P(AppsGridViewDragAndDropTest, MouseDragWithCancelKeepsOrder) {
  size_t kTotalItems = 2;
  model_->PopulateApps(kTotalItems);
  gfx::Point from = GetItemRectOnCurrentPageAt(0, 0).CenterPoint();
  InitiateDrag(AppsGridView::MOUSE, from, apps_grid_view_);
  gfx::Point to = GetItemRectOnCurrentPageAt(0, 1).CenterPoint();

  UpdateDrag(AppsGridView::MOUSE, to, apps_grid_view_, 10 /*steps*/);
  EndDrag(apps_grid_view_, true /*cancel*/);

  EXPECT_EQ(std::string("Item 0,Item 1"), model_->GetModelContent());
  test_api_->LayoutToIdealBounds();
}

// Deleting an item keeps remaining intact.
TEST_P(AppsGridViewDragAndDropTest, MouseDragWithDeleteItemKeepsOrder) {
  size_t kTotalItems = 3;
  model_->PopulateApps(kTotalItems);
  gfx::Point from = GetItemRectOnCurrentPageAt(0, 0).CenterPoint();
  InitiateDrag(AppsGridView::MOUSE, from, apps_grid_view_);
  gfx::Point to = GetItemRectOnCurrentPageAt(0, 1).CenterPoint();

  UpdateDrag(AppsGridView::MOUSE, to, apps_grid_view_, 10 /*steps*/);
  model_->DeleteItem(model_->GetItemName(2));
  EndDrag(apps_grid_view_, false /*cancel*/);

  EXPECT_EQ(std::string("Item 0,Item 1"), model_->GetModelContent());
  test_api_->LayoutToIdealBounds();
}

// Adding a launcher item cancels the drag and respects the order.
TEST_P(AppsGridViewDragAndDropTest, MouseDragWithAddItemKeepsOrder) {
  size_t kTotalItems = 2;
  model_->PopulateApps(kTotalItems);
  gfx::Point from = GetItemRectOnCurrentPageAt(0, 0).CenterPoint();
  InitiateDrag(AppsGridView::MOUSE, from, apps_grid_view_);
  gfx::Point to = GetItemRectOnCurrentPageAt(0, 1).CenterPoint();

  UpdateDrag(AppsGridView::MOUSE, to, apps_grid_view_, 10 /*steps*/);
  model_->CreateAndAddItem("Extra");
  EndDrag(apps_grid_view_, false /*cancel*/);

  EXPECT_EQ(std::string("Item 0,Item 1,Extra"), model_->GetModelContent());
  test_api_->LayoutToIdealBounds();
}

// Regression test for crash bug. https://crbug.com/1166011.
TEST_F(AppsGridViewTest, MoveItemInModelPastEndOfList) {
  model_->PopulateApps(20);

  // I speculate that the item list is missing an item, but PagedViewStructure
  // doesn't know about it. This could happen if an item was deleted during a
  // period that AppsGridView was not observing the list.
  AppListItemList* item_list = model_->top_level_item_list();
  item_list->RemoveObserver(apps_grid_view_);
  DeleteItemAt(item_list, 19);
  item_list->AddObserver(apps_grid_view_);
  ASSERT_EQ(19u, item_list->item_count());

  // Try to move the first item to the end of the page. PagedViewStructure is
  // out of sync with AppListItemList, so it will return a target item list
  // index off the end of the list.
  AppListItemView* first_item = GetItemViewInTopLevelGrid(0);
  MoveItemInModel(first_item, GridIndex(0, 19));

  // No crash. Item moved to the end.
  ASSERT_EQ(19u, item_list->item_count());
  EXPECT_EQ("Item 0", item_list->item_at(18)->id());
}

// Test that control+arrow swaps app within the same page.
TEST_F(AppsGridViewTest, ControlArrowSwapsAppsWithinSamePage) {
  model_->PopulateApps(GetTilesPerPage());

  AppListItemView* moving_item = GetItemViewInTopLevelGrid(0);
  apps_grid_view_->GetFocusManager()->SetFocusedView(moving_item);

  // Test that moving left from 0,0 does not move the app.
  SimulateKeyPress(ui::VKEY_LEFT, ui::EF_CONTROL_DOWN);

  EXPECT_EQ(moving_item, test_api_->GetViewAtVisualIndex(0, 0));
  EXPECT_TRUE(apps_grid_view_->IsSelectedView(moving_item));

  // Test that moving up from 0,0 does not move the app.
  SimulateKeyPress(ui::VKEY_UP, ui::EF_CONTROL_DOWN);

  EXPECT_EQ(moving_item, GetItemViewInTopLevelGrid(0));
  EXPECT_TRUE(apps_grid_view_->IsSelectedView(moving_item));

  // Test that moving right from 0,0 results in a swap with the item adjacent.
  AppListItemView* swapped_item = GetItemViewInTopLevelGrid(1);
  SimulateKeyPress(ui::VKEY_RIGHT, ui::EF_CONTROL_DOWN);

  EXPECT_EQ(moving_item, GetItemViewInTopLevelGrid(1));
  EXPECT_EQ(swapped_item, GetItemViewInTopLevelGrid(0));
  EXPECT_TRUE(apps_grid_view_->IsSelectedView(moving_item));

  // Test that moving down from 0,1 results in a swap with the item at 1,1.
  swapped_item = GetItemViewInTopLevelGrid(apps_grid_view_->cols() + 1);
  SimulateKeyPress(ui::VKEY_DOWN, ui::EF_CONTROL_DOWN);

  EXPECT_EQ(moving_item,
            GetItemViewInTopLevelGrid(apps_grid_view_->cols() + 1));
  EXPECT_EQ(swapped_item, GetItemViewInTopLevelGrid(1));
  EXPECT_TRUE(apps_grid_view_->IsSelectedView(moving_item));

  // Test that moving left from 1,1 results in a swap with the item at 1,0.
  swapped_item = GetItemViewInTopLevelGrid(apps_grid_view_->cols());
  SimulateKeyPress(ui::VKEY_LEFT, ui::EF_CONTROL_DOWN);

  EXPECT_EQ(moving_item, GetItemViewInTopLevelGrid(apps_grid_view_->cols()));
  EXPECT_EQ(swapped_item,
            GetItemViewInTopLevelGrid(apps_grid_view_->cols() + 1));
  EXPECT_TRUE(apps_grid_view_->IsSelectedView(moving_item));

  // Test that moving up from 1,0 results in a swap with the item at 0,0.
  swapped_item = GetItemViewInTopLevelGrid(0);
  SimulateKeyPress(ui::VKEY_UP, ui::EF_CONTROL_DOWN);

  EXPECT_EQ(moving_item, GetItemViewInTopLevelGrid(0));
  EXPECT_EQ(swapped_item, GetItemViewInTopLevelGrid(apps_grid_view_->cols()));
  EXPECT_TRUE(apps_grid_view_->IsSelectedView(moving_item));
}

// Tests that histograms are recorded when apps are moved with control+arrow.
TEST_F(AppsGridViewTest, ControlArrowRecordsHistogramBasic) {
  base::HistogramTester histogram_tester;
  model_->PopulateApps(GetTilesPerPage());

  AppListItemView* moving_item = GetItemViewInTopLevelGrid(0);
  apps_grid_view_->GetFocusManager()->SetFocusedView(moving_item);

  // Make one move right and expect a histogram is recorded.
  SimulateKeyPress(ui::VKEY_RIGHT, ui::EF_CONTROL_DOWN);
  SimulateKeyReleased(ui::VKEY_RIGHT, ui::EF_NONE);

  histogram_tester.ExpectBucketCount("Apps.AppListAppMovingType", 6, 1);

  // Make one move down and expect a histogram is recorded.
  SimulateKeyPress(ui::VKEY_DOWN, ui::EF_CONTROL_DOWN);
  SimulateKeyReleased(ui::VKEY_DOWN, ui::EF_NONE);

  histogram_tester.ExpectBucketCount("Apps.AppListAppMovingType", 6, 2);

  // Make one move up and expect a histogram is recorded.
  SimulateKeyPress(ui::VKEY_UP, ui::EF_CONTROL_DOWN);
  SimulateKeyReleased(ui::VKEY_UP, ui::EF_NONE);

  histogram_tester.ExpectBucketCount("Apps.AppListAppMovingType", 6, 3);

  // Make one move left and expect a histogram is recorded.
  SimulateKeyPress(ui::VKEY_LEFT, ui::EF_CONTROL_DOWN);
  SimulateKeyReleased(ui::VKEY_LEFT, ui::EF_NONE);

  histogram_tester.ExpectBucketCount("Apps.AppListAppMovingType", 6, 4);
}

// Test that histograms do not record when the keyboard move is a no-op.
TEST_F(AppsGridViewTest, ControlArrowDoesNotRecordHistogramWithNoOpMove) {
  base::HistogramTester histogram_tester;
  model_->PopulateApps(GetTilesPerPage());

  AppListItemView* moving_item = GetItemViewInTopLevelGrid(0);
  apps_grid_view_->GetFocusManager()->SetFocusedView(moving_item);

  // Make 2 no-op moves and one successful move from 0,0 ane expect a histogram
  // is recorded only once.
  SimulateKeyPress(ui::VKEY_LEFT, ui::EF_CONTROL_DOWN);
  SimulateKeyReleased(ui::VKEY_LEFT, ui::EF_NONE);

  SimulateKeyPress(ui::VKEY_UP, ui::EF_CONTROL_DOWN);
  SimulateKeyReleased(ui::VKEY_UP, ui::EF_NONE);

  SimulateKeyPress(ui::VKEY_RIGHT, ui::EF_CONTROL_DOWN);
  SimulateKeyReleased(ui::VKEY_RIGHT, ui::EF_NONE);

  histogram_tester.ExpectBucketCount("Apps.AppListAppMovingType", 6, 1);
}

// Tests that histograms only record once for a long move sequence.
TEST_F(AppsGridViewTest, ControlArrowRecordsHistogramOnceWithOneMoveSequence) {
  base::HistogramTester histogram_tester;
  model_->PopulateApps(GetTilesPerPage() * 2);

  AppListItemView* moving_item = GetItemViewInTopLevelGrid(0);
  apps_grid_view_->GetFocusManager()->SetFocusedView(moving_item);

  // Make that a series of moves when the control key is left pressed and expect
  // one histogram is recorded.
  while (GetPaginationModel()->selected_page() != 1) {
    SimulateKeyPress(ui::VKEY_DOWN, ui::EF_CONTROL_DOWN);
    SimulateKeyReleased(ui::VKEY_DOWN, ui::EF_CONTROL_DOWN);
  }
  SimulateKeyReleased(ui::VKEY_DOWN, ui::EF_NONE);

  histogram_tester.ExpectBucketCount("Apps.AppListAppMovingType", 6, 1);
}

// Tests that moving an app down when it is directly below a gap results in a
// swap with the closest item.
TEST_F(AppsGridViewTest, ControlArrowDownToGapOnSamePage) {
  // Add two rows of apps, one full and one with just one app.
  model_->PopulateApps(apps_grid_view_->cols() + 1);

  // Select the far right item.
  AppListItemView* moving_item =
      GetItemViewInTopLevelGrid(apps_grid_view_->cols() - 1);
  AppListItemView* swapped_item =
      GetItemViewInTopLevelGrid(apps_grid_view_->cols());
  apps_grid_view_->GetFocusManager()->SetFocusedView(moving_item);

  // Press down to move the app to the next row. It should take the place of the
  // app on the next row that is closes to the column of |moving_item|.
  SimulateKeyPress(ui::VKEY_DOWN, ui::EF_CONTROL_DOWN);

  EXPECT_EQ(moving_item, GetItemViewInTopLevelGrid(apps_grid_view_->cols()));
  EXPECT_EQ(swapped_item,
            GetItemViewInTopLevelGrid(apps_grid_view_->cols() - 1));
}

// Tests that moving an app up/down/left/right to a full page results in the app
// at the destination slot moving to the source slot (ie. a swap).
TEST_F(AppsGridViewTest, ControlArrowSwapsBetweenFullPages) {
  const int kPages = 3;
  model_->PopulateApps(kPages * GetTilesPerPage());
  // For every item in the first row, ensure an upward move results in the item
  // swapping places with the item directly above it.
  for (int i = 0; i < apps_grid_view_->cols(); ++i) {
    GetPaginationModel()->SelectPage(1, false /*animate*/);
    const GridIndex moved_view_index(1, i);
    apps_grid_view_->GetFocusManager()->SetFocusedView(
        test_api_->GetViewAtIndex(moved_view_index));

    const GridIndex swapped_view_index(
        0,
        apps_grid_view_->cols() * (apps_grid_view_->rows_per_page() - 1) + i);
    AppListItemView* moved_view = test_api_->GetViewAtIndex(moved_view_index);
    AppListItemView* swapped_view =
        test_api_->GetViewAtIndex(swapped_view_index);

    SimulateKeyPress(ui::VKEY_UP, ui::EF_CONTROL_DOWN);

    // |swapped_view| and |moved_view| should swap places when moving up to a
    // full page.
    EXPECT_EQ(swapped_view, test_api_->GetViewAtIndex(moved_view_index));
    EXPECT_EQ(moved_view, test_api_->GetViewAtIndex(swapped_view_index));
    EXPECT_EQ(0, GetPaginationModel()->selected_page());
  }

  // For every item in the last row of a full page, ensure a downward move
  // results in the item swapping places when the target position is occupied.
  for (int i = 0; i < apps_grid_view_->cols(); ++i) {
    GetPaginationModel()->SelectPage(1, false /*animate*/);
    const GridIndex moved_view_index(
        0,
        apps_grid_view_->cols() * (apps_grid_view_->rows_per_page() - 1) + i);
    apps_grid_view_->GetFocusManager()->SetFocusedView(
        test_api_->GetViewAtIndex(moved_view_index));

    const GridIndex swapped_view_index(1, i);
    AppListItemView* moved_view = test_api_->GetViewAtIndex(moved_view_index);
    AppListItemView* swapped_view =
        test_api_->GetViewAtIndex(swapped_view_index);

    SimulateKeyPress(ui::VKEY_DOWN, ui::EF_CONTROL_DOWN);

    // |swapped_view| and |moved_view| should swap places when moving up to a
    // full page.
    EXPECT_EQ(swapped_view, test_api_->GetViewAtIndex(moved_view_index));
    EXPECT_EQ(moved_view, test_api_->GetViewAtIndex(swapped_view_index));
    EXPECT_EQ(1, GetPaginationModel()->selected_page());
  }

  // For the final item on the first page, moving right to a full page should
  // swap with the first item on the next page.
  GetPaginationModel()->SelectPage(0, false /*animate*/);
  GridIndex moved_view_index(
      0, apps_grid_view_->cols() * apps_grid_view_->rows_per_page() - 1);
  GridIndex swapped_view_index(1, 0);
  AppListItemView* moved_view = test_api_->GetViewAtIndex(moved_view_index);
  AppListItemView* swapped_view = test_api_->GetViewAtIndex(swapped_view_index);
  apps_grid_view_->GetFocusManager()->SetFocusedView(
      test_api_->GetViewAtIndex(moved_view_index));

  SimulateKeyPress(ui::VKEY_RIGHT, ui::EF_CONTROL_DOWN);

  EXPECT_EQ(swapped_view, test_api_->GetViewAtIndex(moved_view_index));
  EXPECT_EQ(moved_view, test_api_->GetViewAtIndex(swapped_view_index));
  EXPECT_EQ(1, GetPaginationModel()->selected_page());

  // For the first item on the second page, moving left to a full page should
  // swap with the first item on the previous page.
  swapped_view_index = moved_view_index;
  moved_view_index = GridIndex(1, 0);
  moved_view = test_api_->GetViewAtIndex(moved_view_index);
  swapped_view = test_api_->GetViewAtIndex(swapped_view_index);

  SimulateKeyPress(ui::VKEY_LEFT, ui::EF_CONTROL_DOWN);

  EXPECT_EQ(swapped_view, test_api_->GetViewAtIndex(moved_view_index));
  EXPECT_EQ(moved_view, test_api_->GetViewAtIndex(swapped_view_index));
  EXPECT_EQ(0, GetPaginationModel()->selected_page());
}

// Test that a page can be created while moving apps with the control+arrow.
TEST_F(AppsGridViewTest, ControlArrowDownAndRightCreatesNewPage) {
  base::HistogramTester histogram_tester;
  const int kTilesPerPageStart = GetTilesPerPage();
  model_->PopulateApps(kTilesPerPageStart);

  // Focus the last item on the page.
  AppListItemView* moving_item =
      GetItemViewInTopLevelGrid(kTilesPerPageStart - 1);
  apps_grid_view_->GetFocusManager()->SetFocusedView(moving_item);

  // Test that pressing control-right creates a new page.
  SimulateKeyPress(ui::VKEY_RIGHT, ui::EF_CONTROL_DOWN);

  histogram_tester.ExpectBucketCount("Apps.AppListPageSwitcherSource", 7, 1);
  EXPECT_EQ(moving_item, test_api_->GetViewAtIndex(GridIndex(1, 0)));
  EXPECT_EQ(kTilesPerPageStart - 1, test_api_->AppsOnPage(0));
  EXPECT_EQ(1, GetPaginationModel()->selected_page());
  EXPECT_EQ(2, GetPaginationModel()->total_pages());

  // Reset by moving the app back to the previous page.
  SimulateKeyPress(ui::VKEY_UP, ui::EF_CONTROL_DOWN);

  histogram_tester.ExpectBucketCount("Apps.AppListPageSwitcherSource", 7, 2);

  // Test that control-down creates a new page.
  SimulateKeyPress(ui::VKEY_DOWN, ui::EF_CONTROL_DOWN);

  // The slot where |moving_item| originated should be empty because items get
  // dumped on pages with room, and only swap if the destination page is full.
  EXPECT_EQ(
      nullptr,
      test_api_->GetViewAtIndex(GridIndex(
          0, apps_grid_view_->cols() * apps_grid_view_->rows_per_page() - 1)));
  EXPECT_EQ(moving_item, test_api_->GetViewAtIndex(GridIndex(1, 0)));
  EXPECT_EQ(kTilesPerPageStart - 1, test_api_->AppsOnPage(0));
  EXPECT_EQ(1, test_api_->AppsOnPage(1));
  EXPECT_EQ(1, GetPaginationModel()->selected_page());
  EXPECT_EQ(2, GetPaginationModel()->total_pages());
  histogram_tester.ExpectBucketCount("Apps.AppListPageSwitcherSource", 7, 3);
}

// Tests that a page can be deleted if a lonely app is moved down or right to
// another page.
TEST_F(AppsGridViewTest, ControlArrowUpOrLeftRemovesPage) {
  base::HistogramTester histogram_tester;
  // Move an app so it is by itself on page 1.
  model_->PopulateApps(GetTilesPerPage());
  AppListItemView* moving_item =
      GetItemViewInTopLevelGrid(GetTilesPerPage() - 1);
  apps_grid_view_->GetFocusManager()->SetFocusedView(moving_item);
  SimulateKeyPress(ui::VKEY_DOWN, ui::EF_CONTROL_DOWN);
  histogram_tester.ExpectBucketCount("Apps.AppListPageSwitcherSource", 7, 1);
  EXPECT_EQ(1, GetPaginationModel()->selected_page());
  EXPECT_EQ(2, GetPaginationModel()->total_pages());

  // Move the app up, test that the page is deleted.
  SimulateKeyPress(ui::VKEY_UP, ui::EF_CONTROL_DOWN);

  histogram_tester.ExpectBucketCount("Apps.AppListPageSwitcherSource", 7, 2);
  EXPECT_EQ(0, GetPaginationModel()->selected_page());
  EXPECT_EQ(1, GetPaginationModel()->total_pages());

  // Move the app to be by itself again on page 1.
  SimulateKeyPress(ui::VKEY_DOWN, ui::EF_CONTROL_DOWN);
  histogram_tester.ExpectBucketCount("Apps.AppListPageSwitcherSource", 7, 3);
  EXPECT_EQ(1, GetPaginationModel()->selected_page());
  EXPECT_EQ(2, GetPaginationModel()->total_pages());

  // Move the app left, test that the page is deleted.
  SimulateKeyPress(ui::VKEY_LEFT, ui::EF_CONTROL_DOWN);

  histogram_tester.ExpectBucketCount("Apps.AppListPageSwitcherSource", 7, 4);
  EXPECT_EQ(0, GetPaginationModel()->selected_page());
  EXPECT_EQ(1, GetPaginationModel()->total_pages());
}

// Tests that moving a lonely app on the last page down is a no-op when there
// are no pages below.
TEST_F(AppsGridViewTest, ControlArrowDownOnLastAppOnLastPage) {
  base::HistogramTester histogram_tester;
  // Move an app so it is by itself on page 1.
  model_->PopulateApps(GetTilesPerPage());
  AppListItemView* moving_item =
      GetItemViewInTopLevelGrid(GetTilesPerPage() - 1);
  apps_grid_view_->GetFocusManager()->SetFocusedView(moving_item);
  SimulateKeyPress(ui::VKEY_DOWN, ui::EF_CONTROL_DOWN);
  SimulateKeyReleased(ui::VKEY_DOWN, ui::EF_NONE);
  histogram_tester.ExpectBucketCount("Apps.AppListPageSwitcherSource", 7, 1);
  histogram_tester.ExpectBucketCount("Apps.AppListAppMovingType", 6, 1);
  EXPECT_EQ(1, GetPaginationModel()->selected_page());
  EXPECT_EQ(2, GetPaginationModel()->total_pages());

  // Move the app right, test that nothing changes and no histograms are
  // recorded.
  SimulateKeyPress(ui::VKEY_RIGHT, ui::EF_CONTROL_DOWN);
  SimulateKeyReleased(ui::VKEY_RIGHT, ui::EF_NONE);

  histogram_tester.ExpectBucketCount("Apps.AppListPageSwitcherSource", 7, 1);
  histogram_tester.ExpectBucketCount("Apps.AppListAppMovingType", 6, 1);
  EXPECT_EQ(1, GetPaginationModel()->selected_page());
  EXPECT_EQ(2, GetPaginationModel()->total_pages());

  // Move the app down, test that nothing changes and no histograms are
  // recorded.
  SimulateKeyPress(ui::VKEY_DOWN, ui::EF_CONTROL_DOWN);
  SimulateKeyReleased(ui::VKEY_DOWN, ui::EF_NONE);

  histogram_tester.ExpectBucketCount("Apps.AppListPageSwitcherSource", 7, 1);
  histogram_tester.ExpectBucketCount("Apps.AppListAppMovingType", 6, 1);
  EXPECT_EQ(1, GetPaginationModel()->selected_page());
  EXPECT_EQ(2, GetPaginationModel()->total_pages());
}

// Test that moving an item down or right when it is by itself on a page with a
// page below results in the page deletion.
TEST_F(AppsGridViewTest, ControlArrowDownOrRightRemovesPage) {
  // Move an app so it is by itself on page 1, with another app on page 2.
  model_->PopulateApps(GetTilesPerPage());
  AppListItemView* moving_item =
      GetItemViewInTopLevelGrid(GetTilesPerPage() - 1);
  apps_grid_view_->GetFocusManager()->SetFocusedView(moving_item);
  SimulateKeyPress(ui::VKEY_DOWN, ui::EF_CONTROL_DOWN);
  SimulateKeyPress(ui::VKEY_UP);
  SimulateKeyPress(ui::VKEY_DOWN, ui::EF_CONTROL_DOWN);
  SimulateKeyPress(ui::VKEY_DOWN, ui::EF_CONTROL_DOWN);
  SimulateKeyPress(ui::VKEY_UP);
  // The lonely app is selected on page 1, with a page below it containing one
  // app.
  EXPECT_EQ(1, GetPaginationModel()->selected_page());
  EXPECT_EQ(3, GetPaginationModel()->total_pages());

  // Test that moving the app on page 1 down, deletes the second page and
  // creates a final page with 2 apps.
  SimulateKeyPress(ui::VKEY_DOWN, ui::EF_CONTROL_DOWN);

  EXPECT_EQ(1, GetPaginationModel()->selected_page());
  EXPECT_EQ(2, GetPaginationModel()->total_pages());
  EXPECT_EQ(2, test_api_->AppsOnPage(1));

  // Create a third page, with an app by itself.
  SimulateKeyPress(ui::VKEY_DOWN, ui::EF_CONTROL_DOWN);
  SimulateKeyPress(ui::VKEY_UP);
  EXPECT_EQ(1, GetPaginationModel()->selected_page());
  EXPECT_EQ(3, GetPaginationModel()->total_pages());

  // Test that moving the app right moves the selected app to the third page,
  // and the second page is deleted.
  SimulateKeyPress(ui::VKEY_RIGHT, ui::EF_CONTROL_DOWN);

  EXPECT_EQ(1, GetPaginationModel()->selected_page());
  EXPECT_EQ(2, GetPaginationModel()->total_pages());
  EXPECT_EQ(2, test_api_->AppsOnPage(1));
}

// Tests that control + shift + arrow puts |selected_item_| into a folder or
// creates a folder if one does not exist.
TEST_F(AppsGridViewTest, ControlShiftArrowFoldersItemBasic) {
  base::HistogramTester histogram_tester;
  model_->PopulateApps(GetTilesPerPage());
  // Select the first item in the grid, folder it with the item to the right.
  AppListItemView* first_item = GetItemViewInTopLevelGrid(0);
  const std::string first_item_id = first_item->item()->id();
  const std::string second_item_id = GetItemViewInTopLevelGrid(1)->item()->id();
  apps_grid_view_->GetFocusManager()->SetFocusedView(first_item);

  SimulateKeyPress(ui::VKEY_RIGHT, ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN);

  // Test that the first item in the grid is now a folder with the first and
  // second items, and that the folder is the selected view.
  AppListItemView* new_folder = GetItemViewInTopLevelGrid(0);
  ASSERT_TRUE(apps_grid_view_->IsSelectedView(new_folder));
  AppListFolderItem* folder_item =
      static_cast<AppListFolderItem*>(new_folder->item());
  EXPECT_TRUE(folder_item->is_folder());
  EXPECT_EQ(2u, folder_item->ChildItemCount());
  EXPECT_TRUE(folder_item->FindChildItem(first_item_id));
  EXPECT_TRUE(folder_item->FindChildItem(second_item_id));
  histogram_tester.ExpectBucketCount("Apps.AppListAppMovingType",
                                     kMoveByKeyboardIntoFolder, 1);

  // Test that, when a folder is selected, control+shift+arrow does nothing.
  SimulateKeyPress(ui::VKEY_RIGHT, ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN);

  EXPECT_TRUE(apps_grid_view_->IsSelectedView(new_folder));
  EXPECT_EQ(2u, folder_item->ChildItemCount());
  histogram_tester.ExpectBucketCount("Apps.AppListAppMovingType",
                                     kMoveByKeyboardIntoFolder, 1);

  // Move selection to the item to the right of the folder and put it in the
  // folder.
  apps_grid_view_->GetFocusManager()->SetFocusedView(
      GetItemViewInTopLevelGrid(1));

  SimulateKeyPress(ui::VKEY_LEFT, ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN);

  EXPECT_TRUE(apps_grid_view_->IsSelectedView(new_folder));
  EXPECT_EQ(3u, folder_item->ChildItemCount());
  histogram_tester.ExpectBucketCount("Apps.AppListAppMovingType",
                                     kMoveByKeyboardIntoFolder, 2);

  // Move selection to the item below the folder and put it in the folder.
  SimulateKeyPress(ui::VKEY_DOWN);
  SimulateKeyPress(ui::VKEY_UP, ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN);

  EXPECT_TRUE(apps_grid_view_->IsSelectedView(new_folder));
  EXPECT_EQ(4u, folder_item->ChildItemCount());
  histogram_tester.ExpectBucketCount("Apps.AppListAppMovingType",
                                     kMoveByKeyboardIntoFolder, 3);

  // Move the folder to the second row, then put the item above the folder in
  // the folder.
  SimulateKeyPress(ui::VKEY_DOWN, ui::EF_CONTROL_DOWN);
  SimulateKeyPress(ui::VKEY_UP);
  SimulateKeyPress(ui::VKEY_DOWN, ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN);

  EXPECT_TRUE(apps_grid_view_->IsSelectedView(new_folder));
  EXPECT_EQ(5u, folder_item->ChildItemCount());
  histogram_tester.ExpectBucketCount("Apps.AppListAppMovingType",
                                     kMoveByKeyboardIntoFolder, 4);
}

// Tests that foldering an item that is on a different page fails.
TEST_F(AppsGridViewTest, ControlShiftArrowFailsToFolderAcrossPages) {
  model_->PopulateApps(2 * GetTilesPerPage());

  // For every item on the last row of the first page, test that foldering to
  // the next page fails.
  for (int i = 0; i < apps_grid_view_->cols(); ++i) {
    const GridIndex moved_view_index(
        0,
        apps_grid_view_->cols() * (apps_grid_view_->rows_per_page() - 1) + i);
    AppListItemView* attempted_folder_view =
        test_api_->GetViewAtIndex(moved_view_index);
    apps_grid_view_->GetFocusManager()->SetFocusedView(attempted_folder_view);

    SimulateKeyPress(ui::VKEY_DOWN, ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN);

    EXPECT_EQ(attempted_folder_view,
              test_api_->GetViewAtIndex(moved_view_index));
    EXPECT_EQ(0, GetPaginationModel()->selected_page());
  }
  // The last item on the col is selected, try moving right and test that that
  // fails as well.
  GridIndex moved_view_index(
      0, apps_grid_view_->cols() * apps_grid_view_->rows_per_page() - 1);
  AppListItemView* attempted_folder_view =
      test_api_->GetViewAtIndex(moved_view_index);

  SimulateKeyPress(ui::VKEY_RIGHT, ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN);

  EXPECT_EQ(attempted_folder_view, test_api_->GetViewAtIndex(moved_view_index));

  // Move to the second page and test that foldering up to a new page fails.
  SimulateKeyPress(ui::VKEY_DOWN);

  // Select the first item on the second page.
  moved_view_index = GridIndex(1, 0);
  attempted_folder_view = test_api_->GetViewAtIndex(moved_view_index);

  // Try to folder left to the previous page, it  should fail.
  SimulateKeyPress(ui::VKEY_LEFT, ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN);

  EXPECT_EQ(attempted_folder_view, test_api_->GetViewAtIndex(moved_view_index));

  // For every item on the first row of the second page, test that foldering to
  // the next page fails.
  for (int i = 0; i < apps_grid_view_->cols(); ++i) {
    const GridIndex moved_view_index(1, i);
    AppListItemView* attempted_folder_view =
        test_api_->GetViewAtIndex(moved_view_index);
    apps_grid_view_->GetFocusManager()->SetFocusedView(attempted_folder_view);

    SimulateKeyPress(ui::VKEY_UP, ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN);

    EXPECT_EQ(attempted_folder_view,
              test_api_->GetViewAtIndex(moved_view_index));
    EXPECT_EQ(1, GetPaginationModel()->selected_page());
  }
}

// Tests that foldering the item on the last slot of a page doesn't crash.
TEST_F(AppsGridViewTest, ControlShiftArrowFolderLastItemOnPage) {
  const int kNumberOfApps = 4;
  model_->PopulateApps(kNumberOfApps);
  // Select the second to last item in the grid, folder it with the item to the
  // right.
  AppListItemView* moving_item = GetItemViewInTopLevelGrid(kNumberOfApps - 2);
  const std::string first_item_id = moving_item->item()->id();
  const std::string second_item_id =
      GetItemViewInTopLevelGrid(kNumberOfApps - 1)->item()->id();
  apps_grid_view_->GetFocusManager()->SetFocusedView(moving_item);

  SimulateKeyPress(ui::VKEY_RIGHT, ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN);

  // Test that the first item in the grid is now a folder with the first and
  // second items, and that the folder is the selected view.
  AppListItemView* new_folder = GetItemViewInTopLevelGrid(kNumberOfApps - 2);
  ASSERT_TRUE(apps_grid_view_->IsSelectedView(new_folder));
  AppListFolderItem* folder_item =
      static_cast<AppListFolderItem*>(new_folder->item());
  EXPECT_TRUE(folder_item->is_folder());
  EXPECT_EQ(2u, folder_item->ChildItemCount());
  EXPECT_TRUE(folder_item->FindChildItem(first_item_id));
  EXPECT_TRUE(folder_item->FindChildItem(second_item_id));
}

TEST_P(AppsGridViewDragAndDropTest, MouseDragFlipToNextPage) {
  // Create 3 full pages of apps.
  model_->PopulateApps(3 * GetTilesPerPage());
  gfx::Point item_center = GetItemRectOnCurrentPageAt(0, 0).CenterPoint();
  const gfx::Rect apps_grid_bounds = apps_grid_view_->GetLocalBounds();

  // Drag an item to the bottom to start flipping pages.
  page_flip_waiter_->Reset();
  InitiateDrag(AppsGridView::MOUSE, item_center, apps_grid_view_);
  gfx::Point apps_grid_bottom_center =
      gfx::Point(apps_grid_bounds.width() / 2, apps_grid_bounds.bottom() + 1);
  UpdateDrag(AppsGridView::MOUSE, apps_grid_bottom_center, apps_grid_view_,
             5 /*steps*/);
  while (HasPendingPageFlip(apps_grid_view_)) {
    page_flip_waiter_->Wait();
  }

  // We flip to an extra page created at the end.
  EXPECT_EQ("1,2,3", page_flip_waiter_->selected_pages());
  EXPECT_EQ(3, GetPaginationModel()->selected_page());
  EXPECT_EQ(apps_grid_bottom_center, GetDragViewCenter());

  // End the drag to satisfy checks in AppsGridView destructor.
  EndDrag(apps_grid_view_, /*cancel=*/true);
}

TEST_P(AppsGridViewDragAndDropTest, MouseDragFlipToPreviousPage) {
  // Create 3 full pages of apps.
  model_->PopulateApps(3 * GetTilesPerPage());
  // Select the last page.
  GetPaginationModel()->SelectPage(2, /*animate=*/false);
  gfx::Point item_center = GetItemRectOnCurrentPageAt(0, 0).CenterPoint();

  // Drag an item to the top to start flipping pages.
  page_flip_waiter_->Reset();
  InitiateDrag(AppsGridView::MOUSE, item_center, apps_grid_view_);
  gfx::Point apps_grid_top_center(apps_grid_view_->GetLocalBounds().width() / 2,
                                  0);
  UpdateDrag(AppsGridView::MOUSE, apps_grid_top_center, apps_grid_view_,
             5 /*steps*/);
  while (HasPendingPageFlip(apps_grid_view_)) {
    page_flip_waiter_->Wait();
  }

  // We flipped back to the first page.
  EXPECT_EQ("1,0", page_flip_waiter_->selected_pages());
  EXPECT_EQ(0, GetPaginationModel()->selected_page());
  EXPECT_EQ(apps_grid_top_center, GetDragViewCenter());

  // End the drag to satisfy checks in AppsGridView destructor.
  EndDrag(apps_grid_view_, /*cancel=*/true);
}

TEST_P(AppsGridViewDragAndDropTest, UpdateFolderBackgroundOnCancelDrag) {
  const int kTotalItems = 4;
  TestAppsGridViewFolderDelegate folder_delegate;
  apps_grid_view_->set_folder_delegate(&folder_delegate);
  model_->PopulateApps(kTotalItems);
  gfx::Point mouse_from = GetItemRectOnCurrentPageAt(0, 0).CenterPoint();
  gfx::Point mouse_to = GetItemRectOnCurrentPageAt(0, 1).CenterPoint();

  // Starts a mouse drag and then cancels it.
  SimulateDrag(AppsGridView::MOUSE, mouse_from, mouse_to);
  EndDrag(apps_grid_view_, true /*cancel*/);

  EXPECT_EQ(std::string("Item 0,Item 1,Item 2,Item 3"),
            model_->GetModelContent());
}

// Test focus change before dragging an item. (See https://crbug.com/834682)
TEST_F(AppsGridViewTest, FocusOfDraggedViewBeforeDrag) {
  model_->PopulateApps(1);
  contents_view_->apps_container_view()->Layout();
  auto* search_box = contents_view_->GetSearchBoxView()->search_box();
  auto* item_view = apps_grid_view_->view_model()->view_at(0);

  EXPECT_TRUE(search_box->HasFocus());
  EXPECT_FALSE(item_view->HasFocus());
}

// Test focus change during dragging an item. (See https://crbug.com/834682)
TEST_P(AppsGridViewDragAndDropTest, FocusOfDraggedViewDuringDrag) {
  model_->PopulateApps(1);
  contents_view_->apps_container_view()->Layout();
  auto* search_box = contents_view_->GetSearchBoxView()->search_box();
  auto* item_view = apps_grid_view_->view_model()->view_at(0);
  const gfx::Point from = GetItemRectOnCurrentPageAt(0, 0).CenterPoint();
  InitiateDrag(AppsGridView::MOUSE, from, apps_grid_view_);
  const gfx::Point to = GetItemRectOnCurrentPageAt(0, 1).CenterPoint();

  // Dragging the item towards its right.
  UpdateDrag(AppsGridView::MOUSE, to, apps_grid_view_, 10 /*steps*/);

  EXPECT_FALSE(search_box->HasFocus());
  EXPECT_TRUE(item_view->HasFocus());

  EndDrag(apps_grid_view_, false /*cancel*/);
}

// Test focus change after dragging an item. (See https://crbug.com/834682)
TEST_P(AppsGridViewDragAndDropTest, FocusOfDraggedViewAfterDrag) {
  model_->PopulateApps(1);
  contents_view_->apps_container_view()->Layout();
  auto* search_box = contents_view_->GetSearchBoxView()->search_box();
  auto* item_view = apps_grid_view_->view_model()->view_at(0);
  const gfx::Point from = GetItemRectOnCurrentPageAt(0, 0).CenterPoint();
  InitiateDrag(AppsGridView::MOUSE, from, apps_grid_view_);
  const gfx::Point to = GetItemRectOnCurrentPageAt(0, 1).CenterPoint();

  UpdateDrag(AppsGridView::MOUSE, to, apps_grid_view_, 10 /*steps*/);
  EndDrag(apps_grid_view_, false /*cancel*/);

  EXPECT_FALSE(search_box->HasFocus());
  EXPECT_TRUE(item_view->HasFocus());
}

TEST_P(AppsGridViewTabletTest, Basic) {
  base::HistogramTester histogram_tester;

  model_->PopulateApps(GetTilesPerPage() + 1);
  EXPECT_EQ(2, GetPaginationModel()->total_pages());

  gfx::Point apps_grid_view_origin =
      apps_grid_view_->GetBoundsInScreen().origin();
  ui::GestureEvent scroll_begin(
      apps_grid_view_origin.x(), apps_grid_view_origin.y(), 0,
      base::TimeTicks(),
      ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_BEGIN, 0, -1));
  ui::GestureEvent scroll_update(
      apps_grid_view_origin.x(), apps_grid_view_origin.y(), 0,
      base::TimeTicks(),
      ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_UPDATE, 0, -10));
  ui::GestureEvent scroll_end(
      apps_grid_view_origin.x(), apps_grid_view_origin.y(), 0,
      base::TimeTicks(), ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_END));

  // Drag up on the app grid when on page 1, this should move the AppsGridView
  // but not the AppListView.
  apps_grid_view_->OnGestureEvent(&scroll_begin);
  EXPECT_TRUE(scroll_begin.handled());
  histogram_tester.ExpectTotalCount(
      "Apps.PaginationTransition.DragScroll.PresentationTime.TabletMode", 0);

  apps_grid_view_->OnGestureEvent(&scroll_update);
  EXPECT_TRUE(scroll_update.handled());
  ASSERT_FALSE(app_list_view_->is_in_drag());
  ASSERT_NE(0, GetPaginationModel()->transition().progress);
  histogram_tester.ExpectTotalCount(
      "Apps.PaginationTransition.DragScroll.PresentationTime.TabletMode", 1);
  histogram_tester.ExpectTotalCount(
      "Apps.PaginationTransition.DragScroll.PresentationTime.MaxLatency."
      "TabletMode",
      0);

  apps_grid_view_->OnGestureEvent(&scroll_end);

  histogram_tester.ExpectTotalCount(
      "Apps.PaginationTransition.DragScroll.PresentationTime.TabletMode", 1);
  histogram_tester.ExpectTotalCount(
      "Apps.PaginationTransition.DragScroll.PresentationTime.MaxLatency."
      "TabletMode",
      1);
}

// Make sure that a folder icon resets background blur after scrolling the
// apps grid without completing any transition (See
// https://crbug.com/1049275). The background blur is masked by the apps
// grid's layer mask.
TEST_P(AppsGridViewTabletTest, EnsureBlurAfterScrollingWithoutTransition) {
  // Create a folder with 2 apps. Then add apps until a second page is
  // created.
  model_->CreateAndPopulateFolderWithApps(2);
  model_->PopulateApps(GetTilesPerPage());
  EXPECT_EQ(2, GetPaginationModel()->total_pages());

  gfx::Point apps_grid_view_origin =
      apps_grid_view_->GetBoundsInScreen().origin();
  ui::GestureEvent scroll_begin(
      apps_grid_view_origin.x(), apps_grid_view_origin.y(), 0,
      base::TimeTicks(),
      ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_BEGIN, 0, -1));
  ui::GestureEvent scroll_update_upwards(
      apps_grid_view_origin.x(), apps_grid_view_origin.y(), 0,
      base::TimeTicks(),
      ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_UPDATE, 0, -10));
  ui::GestureEvent scroll_update_downwards(
      apps_grid_view_origin.x(), apps_grid_view_origin.y(), 0,
      base::TimeTicks(),
      ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_UPDATE, 0, 15));
  ui::GestureEvent scroll_end(
      apps_grid_view_origin.x(), apps_grid_view_origin.y(), 0,
      base::TimeTicks(), ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_END));

  AppListItemView* folder_view = GetItemViewInTopLevelGrid(0);
  ASSERT_TRUE(folder_view->is_folder());
  ASSERT_FALSE(apps_grid_view_->layer()->layer_mask_layer());

  // On the first page drag upwards, there should not be a page switch and the
  // layer mask should make the folder lose blur.
  ASSERT_EQ(0, GetPaginationModel()->selected_page());
  apps_grid_view_->OnGestureEvent(&scroll_begin);
  EXPECT_TRUE(scroll_begin.handled());
  apps_grid_view_->OnGestureEvent(&scroll_update_upwards);
  EXPECT_TRUE(scroll_update_upwards.handled());

  ASSERT_EQ(0, GetPaginationModel()->selected_page());
  ASSERT_TRUE(apps_grid_view_->layer()->layer_mask_layer());

  // Continue drag, now switching directions and release. There shouldn't be
  // any transition and the mask layer should've been reset.
  apps_grid_view_->OnGestureEvent(&scroll_update_downwards);
  EXPECT_TRUE(scroll_update_downwards.handled());
  apps_grid_view_->OnGestureEvent(&scroll_end);
  EXPECT_TRUE(scroll_end.handled());

  EXPECT_FALSE(GetPaginationModel()->has_transition());
  EXPECT_FALSE(apps_grid_view_->layer()->layer_mask_layer());
}

TEST_F(AppsGridViewTest, PopulateAppsGridWithTwoApps) {
  const int kApps = 2;
  model_->PopulateApps(kApps);

  // There's only one page and both items are in that page.
  EXPECT_EQ(0, GetPaginationModel()->selected_page());
  EXPECT_EQ(1, GetPaginationModel()->total_pages());
  TestAppListItemViewIndice();
  const views::ViewModelT<AppListItemView>* view_model =
      apps_grid_view_->view_model();
  EXPECT_EQ(2, view_model->view_size());
  EXPECT_EQ(view_model->view_at(0),
            test_api_->GetViewAtVisualIndex(0 /* page */, 0 /* slot */));
  EXPECT_EQ("Item 0", view_model->view_at(0)->item()->id());
  EXPECT_EQ(view_model->view_at(1),
            test_api_->GetViewAtVisualIndex(0 /* page */, 1 /* slot */));
  EXPECT_EQ("Item 1", view_model->view_at(1)->item()->id());
  EXPECT_EQ(std::string("Item 0,Item 1"), model_->GetModelContent());
}

TEST_F(AppsGridViewTest, PopulateAppsGridWithAFolder) {
  // Creates a folder item.
  const size_t kTotalItems = GetAppListConfig().max_folder_items_per_page();
  AppListFolderItem* folder_item =
      model_->CreateAndPopulateFolderWithApps(kTotalItems);

  // Open the folder and check it's contents.
  test_api_->Update();
  test_api_->PressItemAt(0);

  EXPECT_EQ(1u, model_->top_level_item_list()->item_count());
  EXPECT_EQ(AppListFolderItem::kItemType,
            model_->top_level_item_list()->item_at(0)->GetItemType());
  EXPECT_EQ(kTotalItems, folder_item->ChildItemCount());
  EXPECT_EQ(4, folder_apps_grid_view()->cols());
  EXPECT_EQ(4, folder_apps_grid_view()->rows_per_page());
  ash::PaginationModel* folder_pagination_model =
      folder_apps_grid_view()->pagination_model();
  EXPECT_EQ(1, folder_pagination_model->total_pages());
  EXPECT_EQ(0, folder_pagination_model->selected_page());
  EXPECT_TRUE(folder_apps_grid_view()->IsInFolder());
}

TEST_P(AppsGridViewDragAndDropTest, MoveAnItemToNewEmptyPage) {
  const int kApps = 2;
  model_->PopulateApps(kApps);
  const views::ViewModelT<AppListItemView>* view_model =
      apps_grid_view_->view_model();
  gfx::Point from = GetItemRectOnCurrentPageAt(0, 0).CenterPoint();
  InitiateDrag(AppsGridView::MOUSE, from, apps_grid_view_);
  gfx::Point to_in_next_page =
      test_api_->GetItemTileRectAtVisualIndex(1, 0).CenterPoint();

  // Drag the first item to the page bottom.
  UpdateDragToNeighborPage(true /* next_page */, to_in_next_page);

  // A new second page is created and the first item is put on it.
  EXPECT_EQ("1", page_flip_waiter_->selected_pages());
  EXPECT_EQ(1, GetPaginationModel()->selected_page());
  EXPECT_EQ(2, GetPaginationModel()->total_pages());
  TestAppListItemViewIndice();
  EXPECT_EQ(2, view_model->view_size());
  EXPECT_EQ(view_model->view_at(0),
            test_api_->GetViewAtVisualIndex(0 /* page */, 0 /* slot */));
  EXPECT_EQ("Item 1", view_model->view_at(0)->item()->id());
  EXPECT_EQ(view_model->view_at(1),
            test_api_->GetViewAtVisualIndex(1 /* page */, 0 /* slot */));
  EXPECT_EQ("Item 0", view_model->view_at(1)->item()->id());
  EXPECT_EQ(std::string("Item 1,PageBreakItem,Item 0"),
            model_->GetModelContent());
}

TEST_P(AppsGridViewDragAndDropTest, MoveLastItemToCreateFolderInNextPage) {
  const int kApps = 2;
  model_->PopulateApps(kApps);
  const views::ViewModelT<AppListItemView>* view_model =
      apps_grid_view_->view_model();
  gfx::Point from = GetItemRectOnCurrentPageAt(0, 0).CenterPoint();
  InitiateDrag(AppsGridView::MOUSE, from, apps_grid_view_);
  gfx::Point to_in_next_page =
      test_api_->GetItemTileRectAtVisualIndex(1, 0).CenterPoint();

  // Drag the first item to next page and drag the second item to overlap with
  // the first item.
  UpdateDragToNeighborPage(true /* next_page */, to_in_next_page);
  GetPaginationModel()->SelectPage(0, false);
  InitiateDrag(AppsGridView::MOUSE, from, apps_grid_view_);
  UpdateDragToNeighborPage(true /* next_page */, to_in_next_page);

  // A new folder is created on second page, but since the first page is
  // empty, the page is removed and the new folder ends up on first page.
  EXPECT_EQ(1, GetPaginationModel()->total_pages());
  EXPECT_EQ("1,0", page_flip_waiter_->selected_pages());
  EXPECT_EQ(0, GetPaginationModel()->selected_page());
  TestAppListItemViewIndice();
  EXPECT_EQ(1, view_model->view_size());
  EXPECT_EQ(view_model->view_at(0),
            test_api_->GetViewAtVisualIndex(0 /* page */, 0 /* slot */));
  const AppListItem* folder_item = view_model->view_at(0)->item();
  EXPECT_TRUE(folder_item->is_folder());
  // The "page break" item remains, but it will be removed later in
  // AppListSyncableService.
  EXPECT_EQ(std::string("PageBreakItem," + folder_item->id()),
            model_->GetModelContent());
}

TEST_P(AppsGridViewDragAndDropTest, MoveLastItemForReorderInNextPage) {
  const int kApps = 2;
  model_->PopulateApps(kApps);
  const views::ViewModelT<AppListItemView>* view_model =
      apps_grid_view_->view_model();
  gfx::Point from = GetItemRectOnCurrentPageAt(0, 0).CenterPoint();
  InitiateDrag(AppsGridView::MOUSE, from, apps_grid_view_);
  gfx::Rect tile_rect = test_api_->GetItemTileRectAtVisualIndex(1, 0);
  gfx::Point to_in_next_page = tile_rect.CenterPoint();
  to_in_next_page.set_x(tile_rect.x());

  // Drag the first item to next page and drag the second item to the left of
  // the first item.
  UpdateDragToNeighborPage(true /* next_page */, to_in_next_page);
  GetPaginationModel()->SelectPage(0, false);
  InitiateDrag(AppsGridView::MOUSE, from, apps_grid_view_);
  UpdateDragToNeighborPage(true /* next_page */, to_in_next_page);

  // The second item is put on the left of the first item, but since the first
  // page is empty, the page is removed and both items end up on first page.
  EXPECT_EQ("1,0", page_flip_waiter_->selected_pages());
  EXPECT_EQ(0, GetPaginationModel()->selected_page());
  TestAppListItemViewIndice();
  EXPECT_EQ(2, view_model->view_size());
  EXPECT_EQ(view_model->view_at(0),
            test_api_->GetViewAtVisualIndex(0 /* page */, 0 /* slot */));
  EXPECT_EQ("Item 1", view_model->view_at(0)->item()->id());
  EXPECT_EQ(view_model->view_at(1),
            test_api_->GetViewAtVisualIndex(0 /* page */, 1 /* slot */));
  EXPECT_EQ("Item 0", view_model->view_at(1)->item()->id());
  // The "page break" item remains, but it will be removed later in
  // AppListSyncableService.
  EXPECT_EQ(std::string("PageBreakItem,Item 1,Item 0"),
            model_->GetModelContent());
}

TEST_P(AppsGridViewDragAndDropTest, MoveLastItemToNewEmptyPage) {
  const int kApps = 1;
  model_->PopulateApps(kApps);
  const views::ViewModelT<AppListItemView>* view_model =
      apps_grid_view_->view_model();
  gfx::Point from = GetItemRectOnCurrentPageAt(0, 0).CenterPoint();
  InitiateDrag(AppsGridView::MOUSE, from, apps_grid_view_);
  gfx::Point to_in_next_page =
      test_api_->GetItemTileRectAtVisualIndex(1, 0).CenterPoint();

  // Drag the item to next page.
  UpdateDragToNeighborPage(true /* next_page */, to_in_next_page);
  GetPaginationModel()->SelectPage(0, false);
  InitiateDrag(AppsGridView::MOUSE, from, apps_grid_view_);
  UpdateDragToNeighborPage(true /* next_page */, to_in_next_page);

  // The item is put on second page, but since the first page is empty,
  // the page is removed and the item ends up on first page.
  EXPECT_EQ("1,0", page_flip_waiter_->selected_pages());
  EXPECT_EQ(0, GetPaginationModel()->selected_page());
  TestAppListItemViewIndice();
  EXPECT_EQ(1, view_model->view_size());
  EXPECT_EQ(view_model->view_at(0),
            test_api_->GetViewAtVisualIndex(0 /* page */, 0 /* slot */));
  EXPECT_EQ("Item 0", view_model->view_at(0)->item()->id());
  EXPECT_EQ(std::string("Item 0"), model_->GetModelContent());
}

// There's no "page break" item at the end of first page with full grid.
TEST_F(AppsGridViewTest, NoPageBreakItemWithFullGrid) {
  // There are two pages and last item is on second page.
  const int kApps = 2 + GetTilesPerPage();
  model_->PopulateApps(kApps);
  std::string model_content = "Item 0";
  for (int i = 1; i < kApps; ++i)
    model_content.append(",Item " + base::NumberToString(i));

  EXPECT_EQ(model_content, model_->GetModelContent());
}

TEST_P(AppsGridViewDragAndDropTest, PageBreakItemAddedAfterDrag) {
  // There are two pages and last item is on second page.
  const int kApps = 2 + GetTilesPerPage();
  model_->PopulateApps(kApps);
  gfx::Point from = test_api_->GetItemTileRectAtVisualIndex(1, 1).CenterPoint();
  GetPaginationModel()->SelectPage(1, false);
  InitiateDrag(AppsGridView::MOUSE, from, apps_grid_view_);
  gfx::Rect tile_rect = test_api_->GetItemTileRectAtVisualIndex(0, 0);
  gfx::Point to_in_previous_page = tile_rect.CenterPoint();
  to_in_previous_page.set_x(tile_rect.x());

  // Drag the last item to the first item's left position in previous page.
  UpdateDragToNeighborPage(false /* next_page */, to_in_previous_page);

  // A "page break" item is added to split the pages.
  std::string model_content = "Item " + base::NumberToString(kApps - 1);
  for (int i = 1; i < kApps; ++i) {
    model_content.append(",Item " + base::NumberToString(i - 1));
    if (i == GetTilesPerPage() - 1)
      model_content.append(",PageBreakItem");
  }
  EXPECT_EQ(model_content, model_->GetModelContent());
}

TEST_P(AppsGridViewDragAndDropTest, MoveItemToPreviousFullPage) {
  // There are two pages and last item is on second page.
  const int kApps = 2 + GetTilesPerPage();
  model_->PopulateApps(kApps);
  const views::ViewModelT<AppListItemView>* view_model =
      apps_grid_view_->view_model();
  gfx::Point from = test_api_->GetItemTileRectAtVisualIndex(1, 1).CenterPoint();
  GetPaginationModel()->SelectPage(1, false);
  InitiateDrag(AppsGridView::MOUSE, from, apps_grid_view_);
  gfx::Rect tile_rect = test_api_->GetItemTileRectAtVisualIndex(0, 0);
  gfx::Point to_in_previous_page = tile_rect.CenterPoint();
  to_in_previous_page.set_x(tile_rect.x());

  // Drag the last item to the first item's left position in previous
  // page.
  UpdateDragToNeighborPage(false /* next_page */, to_in_previous_page);

  // The dragging is successful, the last item becomes the first item.
  EXPECT_EQ("0", page_flip_waiter_->selected_pages());
  EXPECT_EQ(0, GetPaginationModel()->selected_page());
  TestAppListItemViewIndice();
  EXPECT_EQ(kApps, view_model->view_size());
  for (int i = 0; i < kApps; ++i) {
    int page = i / GetTilesPerPage();
    int slot = i % GetTilesPerPage();
    EXPECT_EQ(view_model->view_at(i),
              test_api_->GetViewAtVisualIndex(page, slot));
    EXPECT_EQ("Item " + base::NumberToString((i + kApps - 1) % kApps),
              view_model->view_at(i)->item()->id());
  }
}

TEST_P(AppsGridViewDragAndDropTest, MoveItemSubsequentDragKeepPageBreak) {
  // There are two pages and last item is on second page.
  const int kApps = 2 + GetTilesPerPage();
  model_->PopulateApps(kApps);
  const views::ViewModelT<AppListItemView>* view_model =
      apps_grid_view_->view_model();
  gfx::Point from = test_api_->GetItemTileRectAtVisualIndex(1, 1).CenterPoint();
  GetPaginationModel()->SelectPage(1, false);
  InitiateDrag(AppsGridView::MOUSE, from, apps_grid_view_);
  gfx::Rect tile_rect = test_api_->GetItemTileRectAtVisualIndex(0, 0);
  gfx::Point to_in_previous_page = tile_rect.CenterPoint();
  to_in_previous_page.set_x(tile_rect.x());

  // Drag the last item to the first item's left position in previous
  // page twice.
  UpdateDragToNeighborPage(false /* next_page */, to_in_previous_page);
  // Again drag the last item to the first item's left position in previous
  // page.
  GetPaginationModel()->SelectPage(1, false);
  InitiateDrag(AppsGridView::MOUSE, from, apps_grid_view_);
  UpdateDragToNeighborPage(false /* next_page */, to_in_previous_page);

  // The dragging is successful, the last item becomes the first item again.
  EXPECT_EQ("0", page_flip_waiter_->selected_pages());
  EXPECT_EQ(0, GetPaginationModel()->selected_page());
  TestAppListItemViewIndice();
  EXPECT_EQ(kApps, view_model->view_size());
  for (int i = 0; i < kApps; ++i) {
    int page = i / GetTilesPerPage();
    int slot = i % GetTilesPerPage();
    EXPECT_EQ(view_model->view_at(i),
              test_api_->GetViewAtVisualIndex(page, slot));
    EXPECT_EQ("Item " + base::NumberToString((i + kApps - 2) % kApps),
              view_model->view_at(i)->item()->id());
  }
  // A "page break" item still exists.
  std::string model_content = "Item " + base::NumberToString(kApps - 2) +
                              ",Item " + base::NumberToString(kApps - 1);
  for (int i = 2; i < kApps; ++i) {
    model_content.append(",Item " + base::NumberToString(i - 2));
    if (i == GetTilesPerPage() - 1)
      model_content.append(",PageBreakItem");
  }
  EXPECT_EQ(model_content, model_->GetModelContent());
}

TEST_F(AppsGridViewTest, CreateANewPageWithKeyboardLogsMetrics) {
  base::HistogramTester histogram_tester;
  model_->PopulateApps(2);

  // Select first app and move it with the keyboard down to create a new page.
  AppListItemView* moving_item = GetItemViewInTopLevelGrid(0);
  apps_grid_view_->GetFocusManager()->SetFocusedView(moving_item);
  SimulateKeyPress(ui::VKEY_DOWN, ui::EF_CONTROL_DOWN);
  SimulateKeyReleased(ui::VKEY_DOWN, ui::EF_NONE);

  ASSERT_EQ(GetPaginationModel()->total_pages(), 2);
  histogram_tester.ExpectBucketCount(
      "Apps.AppList.AppsGridAddPage",
      AppListPageCreationType::kMovingAppWithKeyboard, 1);
}

TEST_P(AppsGridViewDragAndDropTest, CreateANewPageByDraggingLogsMetrics) {
  base::HistogramTester histogram_tester;
  model_->PopulateApps(2);
  gfx::Point from = GetItemRectOnCurrentPageAt(0, 0).CenterPoint();
  InitiateDrag(AppsGridView::MOUSE, from, apps_grid_view_);
  const gfx::Rect apps_grid_bounds = apps_grid_view_->GetLocalBounds();
  gfx::Point to =
      gfx::Point(apps_grid_bounds.width() / 2, apps_grid_bounds.bottom() + 1);

  // Drag down the first item until a new page is created.
  // For fullscreen, drag to the bottom/right of bounds.
  page_flip_waiter_->Reset();
  UpdateDrag(AppsGridView::MOUSE, to, apps_grid_view_);
  while (HasPendingPageFlip(apps_grid_view_))
    page_flip_waiter_->Wait();
  EndDrag(apps_grid_view_, false /*cancel*/);

  ASSERT_EQ(GetPaginationModel()->total_pages(), 2);
  histogram_tester.ExpectBucketCount("Apps.AppList.AppsGridAddPage",
                                     AppListPageCreationType::kDraggingApp, 1);
}

TEST_F(AppsGridViewTest, CreateANewPageByAddingAppLogsMetrics) {
  base::HistogramTester histogram_tester;
  model_->PopulateApps(GetTilesPerPage());

  // Add an item to simulate installing or syncing, the metric should be
  // recorded.
  model_->CreateAndAddItem("Extra App");

  ASSERT_EQ(GetPaginationModel()->total_pages(), 2);
  histogram_tester.ExpectBucketCount("Apps.AppList.AppsGridAddPage",
                                     AppListPageCreationType::kSyncOrInstall,
                                     1);
}

TEST_P(AppsGridViewCardifiedStateTest, PeekingCardOnLastPage) {
  // Create only one page with two apps.
  model_->PopulateApps(2);

  // Start cardified apps grid.
  const gfx::Point from = GetItemRectOnCurrentPageAt(0, 0).CenterPoint();
  InitiateDrag(AppsGridView::MOUSE, from, apps_grid_view_);

  EXPECT_TRUE(apps_grid_view_->cardified_state_for_testing());
  EXPECT_EQ(2, apps_grid_view_->BackgroundCardCountForTesting());

  EndDrag(apps_grid_view_, false /*cancel*/);
}

TEST_P(AppsGridViewCardifiedStateTest, BackgroundCardBounds) {
  model_->PopulateApps(30);

  gfx::NativeView parent = GetContext();
  parent->SetBounds(gfx::Rect(gfx::Point(0, 0), gfx::Size(1024, 768)));
  app_list_view_->OnParentWindowBoundsChanged();
  apps_grid_view_->GetWidget()->LayoutRootViewIfNecessary();

  // Enter cardified state.
  const gfx::Point from = GetItemRectOnCurrentPageAt(0, 0).CenterPoint();
  InitiateDrag(AppsGridView::MOUSE, from, apps_grid_view_);
  ASSERT_TRUE(apps_grid_view_->cardified_state_for_testing());
  ASSERT_EQ(3, apps_grid_view_->BackgroundCardCountForTesting());

  // Verify that all items in the current page fit within the background card.
  gfx::Rect background_card_bounds =
      apps_grid_view_->GetBackgroundCardBoundsForTesting(0);
  gfx::Rect clip_rect = apps_grid_view_->layer()->clip_rect();
  gfx::Rect first_item_bounds = GetItemRectOnCurrentPageAt(0, 0);

  EXPECT_TRUE(background_card_bounds.Contains(first_item_bounds))
      << " background card bounds " << background_card_bounds.ToString()
      << " item bounds " << first_item_bounds.ToString();
  EXPECT_TRUE(clip_rect.Contains(first_item_bounds))
      << " clip rect " << clip_rect.ToString() << " item bounds "
      << first_item_bounds.ToString();

  gfx::Rect last_item_bounds = GetItemRectOnCurrentPageAt(3, 4);
  EXPECT_TRUE(background_card_bounds.Contains(last_item_bounds))
      << " background card bounds " << background_card_bounds.ToString()
      << " item bounds " << last_item_bounds.ToString();
  EXPECT_TRUE(clip_rect.Contains(last_item_bounds))
      << " clip rect " << clip_rect.ToString() << " item bounds "
      << last_item_bounds.ToString();

  // Simulate rotation by updating the bounds of the widget in which the app
  // list was shown.
  parent->SetBounds(gfx::Rect(gfx::Point(0, 0), gfx::Size(768, 1024)));
  app_list_view_->OnParentWindowBoundsChanged();
  apps_grid_view_->GetWidget()->LayoutRootViewIfNecessary();

  ASSERT_TRUE(apps_grid_view_->cardified_state_for_testing());
  ASSERT_EQ(3, apps_grid_view_->BackgroundCardCountForTesting());

  // Verify that all items in the current page fit within the background card.
  background_card_bounds =
      apps_grid_view_->GetBackgroundCardBoundsForTesting(0);
  clip_rect = apps_grid_view_->layer()->clip_rect();
  first_item_bounds = GetItemRectOnCurrentPageAt(0, 0);

  EXPECT_TRUE(background_card_bounds.Contains(first_item_bounds))
      << " background card bounds " << background_card_bounds.ToString()
      << " item bounds " << first_item_bounds.ToString();
  EXPECT_TRUE(clip_rect.Contains(first_item_bounds))
      << " clip rect " << clip_rect.ToString() << " item bounds "
      << first_item_bounds.ToString();

  last_item_bounds = GetItemRectOnCurrentPageAt(4, 3);
  EXPECT_TRUE(background_card_bounds.Contains(last_item_bounds))
      << " background card bounds " << background_card_bounds.ToString()
      << " item bounds " << last_item_bounds.ToString();
  EXPECT_TRUE(clip_rect.Contains(last_item_bounds))
      << " clip rect " << clip_rect.ToString() << " item bounds "
      << last_item_bounds.ToString();

  EndDrag(apps_grid_view_, false /*cancel*/);
  EXPECT_EQ(gfx::Rect(), apps_grid_view_->layer()->clip_rect());
  EXPECT_FALSE(apps_grid_view_->cardified_state_for_testing());
  EXPECT_EQ(0, apps_grid_view_->BackgroundCardCountForTesting());
}

TEST_P(AppsGridViewCardifiedStateTest, BackgroundCardBoundsOnSecondPage) {
  model_->PopulateApps(30);

  gfx::NativeView parent = GetContext();
  parent->SetBounds(gfx::Rect(gfx::Point(0, 0), gfx::Size(1024, 768)));
  app_list_view_->OnParentWindowBoundsChanged();
  apps_grid_view_->GetWidget()->LayoutRootViewIfNecessary();

  // Enter cardified state, and drag the item to the second apps grid page.
  const gfx::Point from = GetItemRectOnCurrentPageAt(0, 0).CenterPoint();
  InitiateDrag(AppsGridView::MOUSE, from, apps_grid_view_);
  const gfx::Point to_in_next_page =
      test_api_->GetItemTileRectAtVisualIndex(1, 0).CenterPoint();
  // Drag the first item to the next page to create another page.
  UpdateDragToNeighborPage(true /* next_page */, to_in_next_page);

  // Trigger cardified state again.
  InitiateDrag(AppsGridView::MOUSE, from, apps_grid_view_);

  ASSERT_TRUE(apps_grid_view_->cardified_state_for_testing());
  ASSERT_EQ(3, apps_grid_view_->BackgroundCardCountForTesting());

  // Verify that all items in the current page fit within the background card.
  gfx::Rect background_card_bounds =
      apps_grid_view_->GetBackgroundCardBoundsForTesting(1);
  gfx::Rect clip_rect = apps_grid_view_->layer()->clip_rect();
  gfx::Rect first_item_bounds = GetItemRectOnCurrentPageAt(0, 0);

  EXPECT_TRUE(background_card_bounds.Contains(first_item_bounds))
      << " background card bounds " << background_card_bounds.ToString()
      << " item bounds " << first_item_bounds.ToString();
  EXPECT_TRUE(clip_rect.Contains(first_item_bounds))
      << " clip rect " << clip_rect.ToString() << " item bounds "
      << first_item_bounds.ToString();

  gfx::Rect last_item_bounds = GetItemRectOnCurrentPageAt(3, 4);
  EXPECT_TRUE(background_card_bounds.Contains(last_item_bounds))
      << " background card bounds " << background_card_bounds.ToString()
      << " item bounds " << last_item_bounds.ToString();
  EXPECT_TRUE(clip_rect.Contains(last_item_bounds))
      << " clip rect " << clip_rect.ToString() << " item bounds "
      << last_item_bounds.ToString();

  // Simulate rotation by updating the bounds of the widget in which the app
  // list was shown.
  parent->SetBounds(gfx::Rect(gfx::Point(0, 0), gfx::Size(768, 1024)));
  app_list_view_->OnParentWindowBoundsChanged();
  apps_grid_view_->GetWidget()->LayoutRootViewIfNecessary();

  ASSERT_TRUE(apps_grid_view_->cardified_state_for_testing());
  ASSERT_EQ(3, apps_grid_view_->BackgroundCardCountForTesting());

  // Verify that all items in the current page fit within the background card.
  background_card_bounds =
      apps_grid_view_->GetBackgroundCardBoundsForTesting(1);
  clip_rect = apps_grid_view_->layer()->clip_rect();
  first_item_bounds = GetItemRectOnCurrentPageAt(0, 0);

  EXPECT_TRUE(background_card_bounds.Contains(first_item_bounds))
      << " background card bounds " << background_card_bounds.ToString()
      << " item bounds " << first_item_bounds.ToString();
  EXPECT_TRUE(clip_rect.Contains(first_item_bounds))
      << " clip rect " << clip_rect.ToString() << " item bounds "
      << first_item_bounds.ToString();

  last_item_bounds = GetItemRectOnCurrentPageAt(4, 3);
  EXPECT_TRUE(background_card_bounds.Contains(last_item_bounds))
      << " background card bounds " << background_card_bounds.ToString()
      << " item bounds " << last_item_bounds.ToString();
  EXPECT_TRUE(clip_rect.Contains(last_item_bounds))
      << " clip rect " << clip_rect.ToString() << " item bounds "
      << last_item_bounds.ToString();

  EndDrag(apps_grid_view_, false /*cancel*/);
  EXPECT_EQ(gfx::Rect(), apps_grid_view_->layer()->clip_rect());
  EXPECT_FALSE(apps_grid_view_->cardified_state_for_testing());
  EXPECT_EQ(0, apps_grid_view_->BackgroundCardCountForTesting());
}

TEST_P(AppsGridViewCardifiedStateTest,
       PeekingCardOnLastPageAfterCreatingNewPage) {
  // Create only one page with two apps.
  model_->PopulateApps(2);
  const gfx::Point from = GetItemRectOnCurrentPageAt(0, 0).CenterPoint();
  InitiateDrag(AppsGridView::MOUSE, from, apps_grid_view_);
  const gfx::Point to_in_next_page =
      test_api_->GetItemTileRectAtVisualIndex(1, 0).CenterPoint();

  // Drag the first item to the next page to create another page.
  UpdateDragToNeighborPage(true /* next_page */, to_in_next_page);
  // Trigger cardified state again.
  InitiateDrag(AppsGridView::MOUSE, from, apps_grid_view_);

  EXPECT_TRUE(apps_grid_view_->cardified_state_for_testing());
  EXPECT_EQ(3, apps_grid_view_->BackgroundCardCountForTesting());

  EndDrag(apps_grid_view_, false /*cancel*/);
}

TEST_P(AppsGridViewCardifiedStateTest, AppsGridIsCardifiedDuringDrag) {
  // Create only one page with two apps.
  model_->PopulateApps(2);

  const gfx::Point from = GetItemRectOnCurrentPageAt(0, 0).CenterPoint();
  InitiateDrag(AppsGridView::MOUSE, from, apps_grid_view_);

  EXPECT_TRUE(apps_grid_view_->cardified_state_for_testing());

  EndDrag(apps_grid_view_, false /*cancel*/);

  EXPECT_FALSE(apps_grid_view_->cardified_state_for_testing());
}

TEST_P(AppsGridViewCardifiedStateTest,
       DragWithinFolderDoesNotEnterCardifiedState) {
  // Creates a folder item and open it.
  const size_t kTotalItems = GetAppListConfig().max_folder_items_per_page();
  model_->CreateAndPopulateFolderWithApps(kTotalItems);
  test_api_->Update();
  test_api_->PressItemAt(0);
  AppsGridViewTestApi folder_grid_test_api(folder_apps_grid_view());
  const gfx::Point from =
      folder_grid_test_api.GetItemTileRectOnCurrentPageAt(0, 0).CenterPoint();

  // Drag the first folder child within the folder.
  InitiateDrag(AppsGridView::MOUSE, from, folder_apps_grid_view());
  const gfx::Point to =
      folder_grid_test_api.GetItemTileRectOnCurrentPageAt(0, 1).CenterPoint();
  UpdateDrag(AppsGridView::MOUSE, to, folder_apps_grid_view(), 10 /*steps*/);
  // The folder item reparent timer should not be triggered.
  ASSERT_FALSE(folder_apps_grid_view()->FireFolderItemReparentTimerForTest());

  EXPECT_FALSE(apps_grid_view_->cardified_state_for_testing());

  EndDrag(folder_apps_grid_view(), false /*cancel*/);
}

TEST_P(AppsGridViewCardifiedStateTest, DragOutsideFolderEntersCardifiedState) {
  // Create a folder item with some apps and open it.
  model_->CreateAndPopulateFolderWithApps(3);
  test_api_->Update();
  test_api_->PressItemAt(0);
  AppsGridViewTestApi folder_grid_test_api(folder_apps_grid_view());
  const gfx::Point from =
      folder_grid_test_api.GetItemTileRectOnCurrentPageAt(0, 0).CenterPoint();

  // Drag the first folder child out of the folder.
  AppListItemView* drag_view =
      InitiateDrag(AppsGridView::MOUSE, from, folder_apps_grid_view());
  const gfx::Point to =
      app_list_folder_view()->GetLocalBounds().bottom_center() +
      gfx::Vector2d(0, drag_view->height()
                    /*padding to completely exit folder view*/);
  UpdateDrag(AppsGridView::MOUSE, to, folder_apps_grid_view(), 10 /*steps*/);
  // Fire the reparent timer that should be started when an item is dragged out
  // of folder bounds.
  ASSERT_TRUE(folder_apps_grid_view()->FireFolderItemReparentTimerForTest());

  EXPECT_TRUE(apps_grid_view_->cardified_state_for_testing());

  EndDrag(folder_apps_grid_view(), false /*cancel*/);
  EXPECT_FALSE(apps_grid_view_->cardified_state_for_testing());
}

TEST_P(AppsGridViewCardifiedStateTest,
       DragItemIntoFolderStaysCaInCardifiedState) {
  // Create a folder item with some apps. Add another app to the main grid.
  model_->CreateAndPopulateFolderWithApps(2);
  model_->PopulateApps(1);
  const gfx::Point from = GetItemRectOnCurrentPageAt(0, 1).CenterPoint();
  InitiateDrag(AppsGridView::MOUSE, from, apps_grid_view_);

  // Dragging item_1 over folder to expand it.
  const gfx::Point to = GetItemRectOnCurrentPageAt(0, 0).CenterPoint();
  UpdateDrag(AppsGridView::MOUSE, to, apps_grid_view_, 10 /*steps*/);

  EXPECT_TRUE(apps_grid_view_->cardified_state_for_testing());

  EndDrag(apps_grid_view_, false /*cancel*/);
  EXPECT_FALSE(apps_grid_view_->cardified_state_for_testing());
  test_api_->WaitForItemMoveAnimationDone();
  test_api_->LayoutToIdealBounds();
}

}  // namespace test
}  // namespace ash
