// 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 <algorithm>
#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "ash/app_list/app_list_controller_impl.h"
#include "ash/app_list/app_list_metrics.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/test/app_list_test_helper.h"
#include "ash/app_list/views/app_list_bubble_search_page.h"
#include "ash/app_list/views/app_list_bubble_view.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_context_menu.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/paged_apps_grid_view.h"
#include "ash/app_list/views/scrollable_apps_grid_view.h"
#include "ash/app_list/views/search_box_view.h"
#include "ash/app_list/views/search_result_page_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/constants/ash_features.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/shelf_item_delegate.h"
#include "ash/public/cpp/shelf_model.h"
#include "ash/public/cpp/test/test_shelf_item_delegate.h"
#include "ash/shelf/shelf.h"
#include "ash/shelf/shelf_view.h"
#include "ash/shell.h"
#include "ash/test/ash_test_base.h"
#include "ash/test/layer_animation_stopped_waiter.h"
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/bind.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/compositor/scoped_animation_duration_scale_mode.h"
#include "ui/events/event_utils.h"
#include "ui/events/keycodes/keyboard_codes_posix.h"
#include "ui/views/controls/label.h"
#include "ui/views/controls/menu/menu_item_view.h"
#include "ui/views/controls/menu/submenu_view.h"
#include "ui/views/controls/textfield/textfield.h"

namespace ash {
namespace test {

namespace {

constexpr int kNumOfSuggestedApps = 3;

constexpr size_t kMaxItemsPerFolderPage =
    AppListFolderView::kMaxFolderColumns *
    AppListFolderView::kMaxPagedFolderRows;
constexpr size_t kMaxItemsInFolder = 48;

class ShelfItemFactoryFake : public ShelfModel::ShelfItemFactory {
 public:
  virtual ~ShelfItemFactoryFake() = default;

  bool CreateShelfItemForAppId(
      const std::string& app_id,
      ShelfItem* item,
      std::unique_ptr<ShelfItemDelegate>* delegate) override {
    *item = ShelfItem();
    item->id = ShelfID(app_id);
    *delegate = std::make_unique<TestShelfItemDelegate>(item->id);
    return true;
  }
};

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

  PageFlipWaiter(const PageFlipWaiter&) = delete;
  PageFlipWaiter& operator=(const PageFlipWaiter&) = delete;

  ~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_;
  PaginationModel* model_ = nullptr;
  bool wait_ = false;
  std::string selected_pages_;
};

// 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(const WindowDeletionWaiter&) = delete;
  WindowDeletionWaiter& operator=(const WindowDeletionWaiter&) = delete;

  ~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_;
};

// 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 PostPageFlipTask : public PaginationModelObserver {
 public:
  PostPageFlipTask(PaginationModel* model, base::OnceClosure task)
      : model_(model), task_(std::move(task)) {
    model_->AddObserver(this);
  }

  PostPageFlipTask(const PostPageFlipTask&) = delete;
  PostPageFlipTask& operator=(const PostPageFlipTask&) = delete;

  ~PostPageFlipTask() 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 {
    if (task_)
      std::move(task_).Run();
  }
  void TransitionStarted() override {}
  void TransitionChanged() override {}
  void TransitionEnded() override {}

  PaginationModel* model_;
  base::OnceClosure task_;
};

class TestSuggestedSearchResult : public TestSearchResult {
 public:
  TestSuggestedSearchResult() {
    set_display_type(SearchResultDisplayType::kChip);
    set_is_recommendation(true);
  }

  TestSuggestedSearchResult(const TestSuggestedSearchResult&) = delete;
  TestSuggestedSearchResult& operator=(const TestSuggestedSearchResult&) =
      delete;

  ~TestSuggestedSearchResult() override = default;
};

// Counts when the observed view's bounds change.
class BoundsChangeCounter : public views::ViewObserver {
 public:
  explicit BoundsChangeCounter(views::View* observed_view)
      : observed_view_(observed_view) {
    observed_view->AddObserver(this);
  }
  BoundsChangeCounter(const BoundsChangeCounter&) = delete;
  BoundsChangeCounter& operator=(const BoundsChangeCounter&) = delete;
  ~BoundsChangeCounter() override { observed_view_->RemoveObserver(this); }

  //  views::ViewObserver:
  void OnViewBoundsChanged(views::View* observed_view) override {
    ++bounds_change_count_;
  }

  int bounds_change_count() const { return bounds_change_count_; }

 private:
  views::View* const observed_view_;
  int bounds_change_count_ = 0;
};

}  // namespace

// Subclasses should set `is_rtl_`, `create_as_tablet_mode_`, etc. in their
// constructors to indicate which mode to test.
class AppsGridViewTest : public AshTestBase {
 public:
  AppsGridViewTest() = default;
  AppsGridViewTest(const AppsGridViewTest&) = delete;
  AppsGridViewTest& operator=(const AppsGridViewTest&) = delete;
  ~AppsGridViewTest() override = default;

  // testing::Test overrides:
  void SetUp() override {
    if (is_rtl_)
      base::i18n::SetICUDefaultLocale("he");
    std::vector<base::Feature> enabled_features;
    std::vector<base::Feature> disabled_features;
    if (is_productivity_launcher_enabled_) {
      enabled_features.push_back(features::kProductivityLauncher);
    } else {
      disabled_features.push_back(features::kProductivityLauncher);
    }
    if (is_app_sort_enabled_) {
      enabled_features.push_back(features::kLauncherAppSort);
    } else {
      disabled_features.push_back(features::kLauncherAppSort);
    }
    feature_list_.InitWithFeatures(enabled_features, disabled_features);
    AshTestBase::SetUp();

    // Make the display big enough to hold the app list.
    UpdateDisplay("1024x768");

    // Populate some suggested apps.
    search_model_ = std::make_unique<SearchModel>();
    for (size_t i = 0; i < kNumOfSuggestedApps; ++i) {
      search_model_->results()->Add(
          std::make_unique<TestSuggestedSearchResult>());
    }

    // Replace the model before the app list views are created, because some
    // views cache pointers to the model.
    model_ = std::make_unique<test::AppListTestModel>();
    Shell::Get()->app_list_controller()->SetActiveModel(
        /*profile_id=*/1, model_.get(), search_model_.get());

    // Show the app list.
    auto* helper = GetAppListTestHelper();
    if (create_as_tablet_mode_) {
      // The app list will be shown automatically when tablet mode is enabled.
      Shell::Get()->tablet_mode_controller()->SetEnabledForTest(true);
    } else if (features::IsProductivityLauncherEnabled()) {
      helper->ShowAppList();
    } else {
      // Show fullscreen so folders are available.
      helper->Show(GetPrimaryDisplay().id());
      helper->GetAppListView()->SetState(AppListViewState::kFullscreenAllApps);
    }
    // Wait for any show animations to complete.
    base::RunLoop().RunUntilIdle();

    // Cache view pointers to make tests more concise.
    if (!create_as_tablet_mode_ && features::IsProductivityLauncherEnabled()) {
      // AppsGridView is scrollable in clamshell mode with AppListBubble.
      apps_grid_view_ = helper->GetScrollableAppsGridView();
      app_list_folder_view_ = helper->GetBubbleFolderView();
      search_box_view_ = helper->GetBubbleSearchBoxView();
    } else {
      app_list_view_ = helper->GetAppListView();
      app_list_folder_view_ = helper->GetFullscreenFolderView();
      auto* contents_view =
          app_list_view_->app_list_main_view()->contents_view();
      search_box_view_ = contents_view->GetSearchBoxView();
      // AppsGridView is paged in tablet mode and without AppListBubble.
      paged_apps_grid_view_ =
          contents_view->apps_container_view()->apps_grid_view();
      apps_grid_view_ = paged_apps_grid_view_;
      suggestions_container_ = contents_view->apps_container_view()
                                   ->suggestion_chip_container_view_for_test();
      expand_arrow_view_ = contents_view->expand_arrow_view();

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

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

  void TearDown() override {
    page_flip_waiter_.reset();
    PresentationTimeRecorder::SetReportPresentationTimeImmediatelyForTest(
        false);
    AshTestBase::TearDown();
  }

 protected:
  void AnimateFolderViewPageFlip(int target_page) {
    // Folders are only paged without productivity launcher enabled.
    DCHECK(!features::IsProductivityLauncherEnabled());
    PagedAppsGridView* paged_folder_apps_grid_view =
        static_cast<PagedAppsGridView*>(folder_apps_grid_view());
    DCHECK(paged_folder_apps_grid_view->pagination_model()->total_pages() >
           target_page);
    AppsGridViewTestApi folder_grid_test_api(paged_folder_apps_grid_view);
    SetPageFlipDurationForTest(paged_folder_apps_grid_view);
    PageFlipWaiter page_flip_waiter(
        paged_folder_apps_grid_view->pagination_model());
    paged_folder_apps_grid_view->pagination_model()->SelectPage(
        target_page, true /*animate*/);
    while (HasPendingPageFlip(paged_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::Milliseconds(3));
    apps_grid_view->pagination_model()->SetTransitionDurations(
        base::Milliseconds(2), base::Milliseconds(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 apps_grid_view_->app_list_config();
  }

  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 {
    AppsGridViewTestApi temp_test_api(grid_view);
    const int selected_page = GetSelectedPage(grid_view);
    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();
      views::View::ConvertPointToTarget(view->parent(), grid_view,
                                        &view_origin);
      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(int page) const { return test_api_->TilesPerPage(page); }

  PaginationModel* GetPaginationModel() const {
    DCHECK(paged_apps_grid_view_) << "Only available in tablet mode or when "
                                     "ProductivityLauncher is disabled.";
    return paged_apps_grid_view_->pagination_model();
  }

  int GetSelectedPage(AppsGridView* grid_view) const {
    return grid_view->GetSelectedPage();
  }

  int GetTotalPages(AppsGridView* grid_view) const {
    return grid_view->GetTotalPages();
  }

  AppListFolderView* app_list_folder_view() const {
    return app_list_folder_view_;
  }

  AppsGridView* 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(location.x(), location.y(), 0,
                                   base::TimeTicks(),
                                   ui::GestureEventDetails(ui::ET_GESTURE_TAP));
    apps_grid_view_->OnGestureEvent(&gesture_event);
    return gesture_event;
  }

  // Simulates a tap on the point `location` if the test is in tablet mode.
  // Simulates a left click on the point otherwise.
  void SimulateLeftClickOrTapAt(const gfx::Point& location) {
    auto* event_generator = GetEventGenerator();
    if (create_as_tablet_mode_) {
      event_generator->GestureTapAt(location);
      return;
    }

    event_generator->MoveMouseTo(location);
    event_generator->ClickLeftButton();
  }

  // Simulates a long press on the point `location` if the test is in tablet
  // mode. Simulates a right click on the point otherwise. This function can be
  // used to open the context menu.
  void SimulateRightClickOrLongPressAt(const gfx::Point& location) {
    auto* event_generator = GetEventGenerator();
    if (create_as_tablet_mode_) {
      ui::GestureEvent gesture_event(
          location.x(), location.y(), 0, base::TimeTicks(),
          ui::GestureEventDetails(ui::ET_GESTURE_LONG_PRESS));
      event_generator->Dispatch(&gesture_event);
      return;
    }

    event_generator->MoveMouseTo(location);
    event_generator->ClickRightButton();
  }

  // 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->item(), target);
  }

  // Updates the layout of the container for the apps grid. Useful when the
  // test has added apps to the data model and is about to do an operation that
  // depends on item positions.
  void UpdateLayout() {
    if (!create_as_tablet_mode_ && features::IsProductivityLauncherEnabled())
      GetAppListTestHelper()->GetBubbleView()->Layout();
    else
      app_list_view_->Layout();
  }

  AppListItemView* InitiateDragForItemAtCurrentPageAt(
      AppsGridView::Pointer pointer,
      int row,
      int column,
      AppsGridView* apps_grid_view) {
    AppsGridViewTestApi test_api(apps_grid_view);
    const int selected_page = GetSelectedPage(apps_grid_view);
    GridIndex index(selected_page, row * apps_grid_view->cols() + column);
    AppListItemView* view = test_api.GetViewAtIndex(index);
    DCHECK(view);

    gfx::Point from = view->GetLocalBounds().CenterPoint();

    gfx::Point root_from = from;
    gfx::NativeWindow window = apps_grid_view->GetWidget()->GetNativeWindow();
    views::View::ConvertPointToWidget(view, &root_from);
    aura::Window::ConvertPointToTarget(window, window->GetRootWindow(),
                                       &root_from);

    view->InitiateDrag(from, root_from);
    current_drag_location_ = root_from;

    // Call UpdateDrag to trigger |apps_grid_view| change to cardified_state -
    // the cardified state starts only once the drag distance exceeds a drag
    // threshold, so the pointer has to sufficiently move from the original
    // position.
    gfx::Point from_in_grid = from;
    views::View::ConvertPointToTarget(view, apps_grid_view, &from_in_grid);
    UpdateDrag(pointer, from_in_grid + gfx::Vector2d(10, 10), 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);

    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;
  }

  // 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) {
    ASSERT_TRUE(paged_apps_grid_view_)
        << "Only available in tablet mode or when ProductivityLauncher is "
           "disabled.";
    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 = paged_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(paged_apps_grid_view_, &root_to);
    gfx::NativeWindow window = app_list_view_->GetWidget()->GetNativeWindow();
    aura::Window::ConvertPointToTarget(window, window->GetRootWindow(),
                                       &root_to);

    // Update dragging and relayout apps grid view after drag ends.
    PostPageFlipTask task(
        GetPaginationModel(), base::BindLambdaForTesting([&]() {
          ui::MouseEvent drag_event(ui::ET_MOUSE_DRAGGED, to, root_to,
                                    ui::EventTimeForNow(), 0, 0);
          paged_apps_grid_view_->UpdateDragFromItem(AppsGridView::MOUSE,
                                                    drag_event);
        }));
    page_flip_waiter_->Reset();
    UpdateDrag(AppsGridView::MOUSE, point_in_page_flip_buffer,
               paged_apps_grid_view_,
               /*steps=*/10);
    while (HasPendingPageFlip(paged_apps_grid_view_)) {
      page_flip_waiter_->Wait();
    }
    EndDrag(paged_apps_grid_view_, false /*cancel*/);
    test_api_->LayoutToIdealBounds();
  }

  gfx::Point GetDragIconCenter() {
    return test_api_->GetDragIconBoundsInAppsGridView().CenterPoint();
  }

  std::string GetItemMoveTypeHistogramName() {
    return paged_apps_grid_view_ ? "Apps.AppListAppMovingType"
                                 : "Apps.AppListBubbleAppMovingType";
  }

  // May be a PagedAppsGridView or a ScrollableAppsGridView depending on the
  // ProductivityLauncher flag and tablet mode.
  AppsGridView* apps_grid_view_ = nullptr;

  // May be owned by different parent views depending on the
  // ProductivityLauncher flag and tablet mode.
  AppListFolderView* app_list_folder_view_ = nullptr;
  SearchBoxView* search_box_view_ = nullptr;

  // These views exist in tablet mode and when ProductivityLauncher is disabled.
  PagedAppsGridView* paged_apps_grid_view_ = nullptr;
  AppListView* app_list_view_ = nullptr;  // Owned by native widget.
  SearchResultContainerView* suggestions_container_ =
      nullptr;                                    // Owned by |apps_grid_view_|.
  ExpandArrowView* expand_arrow_view_ = nullptr;  // Owned by |apps_grid_view_|.

  std::unique_ptr<AppListTestModel> model_;
  std::unique_ptr<SearchModel> search_model_;
  std::unique_ptr<AppsGridViewTestApi> test_api_;

  // True if the test screen is configured to work with RTL locale.
  bool is_rtl_ = false;
  // True if feature ProductivityLauncher should be enabled.
  bool is_productivity_launcher_enabled_ = false;
  // True if feature LauncherAppSort should be enabled.
  bool is_app_sort_enabled_ = false;
  // 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_;

  base::test::ScopedFeatureList feature_list_;

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

// Tests that only run with ProductivityLauncher disabled, which disables the
// bubble launcher. These can be deleted when ProductivityLauncher is the
// default.
class AppsGridViewNonBubbleTest : public AppsGridViewTest {
 public:
  AppsGridViewNonBubbleTest() { is_productivity_launcher_enabled_ = false; }
};

// Test suite for clamshell mode, parameterized by feature ProductivityLauncher.
class AppsGridViewClamshellTest : public AppsGridViewTest,
                                  public testing::WithParamInterface<bool> {
 public:
  AppsGridViewClamshellTest() {
    is_productivity_launcher_enabled_ = GetParam();
  }
};
INSTANTIATE_TEST_SUITE_P(All, AppsGridViewClamshellTest, testing::Bool());

// Tests suite to test both tablet and clamshell mode behavior, additionally
// parameterized by feature ProductivityLauncher.
class AppsGridViewClamshellAndTabletTest
    : public AppsGridViewTest,
      public testing::WithParamInterface<std::tuple<bool, bool>> {
 public:
  AppsGridViewClamshellAndTabletTest() {
    create_as_tablet_mode_ = std::get<0>(GetParam());
    is_productivity_launcher_enabled_ = std::get<1>(GetParam());
  }
};
INSTANTIATE_TEST_SUITE_P(All,
                         AppsGridViewClamshellAndTabletTest,
                         testing::Combine(testing::Bool(), testing::Bool()));

// Tests suite parameterized by RTL locale.
class AppsGridViewRTLTest : public AppsGridViewTest,
                            public testing::WithParamInterface<bool> {
 public:
  AppsGridViewRTLTest() { is_rtl_ = GetParam(); }
};
INSTANTIATE_TEST_SUITE_P(All, AppsGridViewRTLTest, testing::Bool());

// Tests suite for app list items drag and drop tests. These tests are
// parameterized by RTL locale and feature ProductivityLauncher.
class AppsGridViewDragTest
    : public AppsGridViewTest,
      public testing::WithParamInterface<std::tuple<bool, bool>> {
 public:
  AppsGridViewDragTest() {
    is_rtl_ = std::get<0>(GetParam());
    is_productivity_launcher_enabled_ = std::get<1>(GetParam());
  }

  // AppsGridViewTest:
  void SetUp() override {
    AppsGridViewTest::SetUp();
    ShelfModel::Get()->SetShelfItemFactory(&shelf_item_factory_);
  }

  void TearDown() override {
    ShelfModel::Get()->SetShelfItemFactory(nullptr);
    AppsGridViewTest::TearDown();
  }

 private:
  // Shelf item factory required for test that drag from apps grid to shelf.
  ShelfItemFactoryFake shelf_item_factory_;
};

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

// Drag and drop tests that are not expected to work with AppListBubble.
// Parameterized by RTL locale.
class AppsGridViewDragNonBubbleTest : public AppsGridViewTest,
                                      public testing::WithParamInterface<bool> {
 public:
  AppsGridViewDragNonBubbleTest() {
    is_rtl_ = GetParam();
    is_productivity_launcher_enabled_ = false;
  }
};
INSTANTIATE_TEST_SUITE_P(All, AppsGridViewDragNonBubbleTest, testing::Bool());

// Tests suite to verify behaviour exclusively to cardified state, parameterized
// by RTL locale and AppListBubble.
class AppsGridViewCardifiedStateTest
    : public AppsGridViewTest,
      public testing::WithParamInterface<std::tuple<bool, bool>> {
 public:
  AppsGridViewCardifiedStateTest() {
    is_rtl_ = std::get<0>(GetParam());
    is_productivity_launcher_enabled_ = std::get<1>(GetParam());
    // The productivity launcher in clamshell mode does not use pages / cards,
    // so use tablet mode instead.
    create_as_tablet_mode_ = is_productivity_launcher_enabled_;
  }
};
INSTANTIATE_TEST_SUITE_P(All,
                         AppsGridViewCardifiedStateTest,
                         testing::Combine(testing::Bool(), testing::Bool()));

// Test suite for verifying tablet mode apps grid behaviour, parameterized by
// RTL locale and ProductivityLauncher feature.
class AppsGridViewTabletTest
    : public AppsGridViewTest,
      public testing::WithParamInterface<std::tuple<bool, bool>> {
 public:
  AppsGridViewTabletTest() {
    is_rtl_ = std::get<0>(GetParam());
    is_productivity_launcher_enabled_ = std::get<1>(GetParam());
    create_as_tablet_mode_ = true;
  }
};
INSTANTIATE_TEST_SUITE_P(All,
                         AppsGridViewTabletTest,
                         testing::Combine(testing::Bool(), testing::Bool()));

// Test suite that tests apps sort works on all apps grid, parameterized by
// RTL locale and clamshell/tablet mode.
class AppsGridViewAppSortTest
    : public AppsGridViewTest,
      public testing::WithParamInterface<std::tuple<bool, bool>> {
 public:
  AppsGridViewAppSortTest() {
    is_rtl_ = std::get<0>(GetParam());
    is_productivity_launcher_enabled_ = true;
    is_app_sort_enabled_ = true;
    create_as_tablet_mode_ = std::get<1>(GetParam());
  }
};
INSTANTIATE_TEST_SUITE_P(All,
                         AppsGridViewAppSortTest,
                         testing::Combine(testing::Bool(), testing::Bool()));

// This does not test the font name or weight because ash_unittests returns
// different font lists than chrome (e.g. "DejaVu Sans" instead of "Roboto").
TEST_P(AppsGridViewClamshellTest, AppListItemViewFont) {
  model_->PopulateApps(1);
  AppListItemView* item_view = GetItemViewInTopLevelGrid(0);
  EXPECT_EQ(12, item_view->title()->font_list().GetFontSize());
}

// This does not test the font name or weight because ash_unittests returns
// different font lists than chrome (e.g. "DejaVu Sans" instead of "Roboto").
TEST_P(AppsGridViewTabletTest, AppListItemViewFont) {
  model_->PopulateApps(1);
  AppListItemView* item_view = GetItemViewInTopLevelGrid(0);
  if (is_productivity_launcher_enabled_)
    EXPECT_EQ(13, item_view->title()->font_list().GetFontSize());
  else
    EXPECT_EQ(12, item_view->title()->font_list().GetFontSize());
}

TEST_P(AppsGridViewClamshellTest, 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. Bubble launcher uses different metric names and does not use
// suggestion chips.
TEST_F(AppsGridViewNonBubbleTest, UMATestForLaunchingApps) {
  base::HistogramTester histogram_tester;
  model_->PopulateApps(5);
  UpdateLayout();

  // Select the first app in grid and launch it.
  LeftClickOn(GetItemViewInTopLevelGrid(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.
// TODO(jamescook): Investigate why this fails for bubble launcher.
TEST_F(AppsGridViewTest, MoveItemAcrossRowDoesNotCauseCrash) {
  const int cols = apps_grid_view_->cols();
  ASSERT_LE(0, cols);
  model_->PopulateApps(cols * 2);
  UpdateLayout();

  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());
  EXPECT_TRUE(apps_grid_view_->IsAnimatingView(view0));

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

// TODO(jamescook): Investigate why this fails for bubble launcher.
TEST_F(AppsGridViewTest, MoveItemAcrossRowDoesNotCauseAnimation) {
  const int cols = apps_grid_view_->cols();
  ASSERT_LE(0, cols);
  model_->PopulateApps(cols * 2);
  UpdateLayout();

  // NOTE: Dismissing the app list creates layers for item views as part of the
  // opacity animations, even in tests. https://crbug.com/1246567
  GetAppListTestHelper()->DismissAndRunLoop();
  ASSERT_FALSE(apps_grid_view_->GetWidget()->IsVisible());

  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(apps_grid_view_->IsAnimatingView(view0));
  EXPECT_EQ(view0->bounds(), GetItemRectOnCurrentPageAt(1, 2));
}

// Tests that control + arrow while a suggested chip is focused does not crash.
// Productivity launcher does not use suggestion chips.
TEST_F(AppsGridViewNonBubbleTest, ControlArrowOnSuggestedChip) {
  model_->PopulateApps(5);
  UpdateLayout();
  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_P(AppsGridViewClamshellTest, ItemTooltip) {
  std::string title("a");
  AppListItem* item = model_->CreateAndAddItem(title);
  model_->SetItemName(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(0) + 1);
  UpdateLayout();
  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(0) + 1);
  UpdateLayout();
  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(0) + 1);
  UpdateLayout();
  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);
}

// Tests that taps between apps within the AppsGridView does not result in the
// AppList closing.
TEST_F(AppsGridViewTest, TapsBetweenAppsWontCloseAppList) {
  model_->PopulateApps(2);
  UpdateLayout();
  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());
}

// The bubble launcher uses scrollable folders, so this test disables
// ProductivityLauncher.
TEST_F(AppsGridViewNonBubbleTest, PageResetAfterOpenFolder) {
  model_->CreateAndPopulateFolderWithApps(kMaxItemsInFolder);
  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);
  ASSERT_FALSE(features::IsProductivityLauncherEnabled());
  PaginationModel* pagination_model =
      static_cast<PagedAppsGridView*>(folder_apps_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_P(AppsGridViewClamshellTest, 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();
  AppsGridViewTestApi folder_grid_test_api(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(2, folder_grid_test_api.TilesPerPage(0));
  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(6, folder_grid_test_api.TilesPerPage(0));
  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(9, folder_grid_test_api.TilesPerPage(0));
  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(16, folder_grid_test_api.TilesPerPage(0));
  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(features::IsProductivityLauncherEnabled() ? 20 : 16,
            folder_grid_test_api.TilesPerPage(0));
  app_list_folder_view()->CloseFolderPage();
}

TEST_P(AppsGridViewClamshellTest, 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(GetAppListTestHelper()->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(GetAppListTestHelper()->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(GetAppListTestHelper()->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(GetAppListTestHelper()->IsInFolderView());
  items_grid_view->GetWidget()->LayoutRootViewIfNecessary();
  EXPECT_EQ(items_grid_view->GetBoundsInScreen().size(),
            one_row_folder_view.size());
}

TEST_P(AppsGridViewClamshellTest, 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(GetAppListTestHelper()->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(GetAppListTestHelper()->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(GetAppListTestHelper()->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(kMaxItemsPerFolderPage);
  test_api_->PressItemAt(2);
  EXPECT_TRUE(GetAppListTestHelper()->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 = kMaxItemsPerFolderPage;
  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(GetAppListTestHelper()->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(GetAppListTestHelper()->IsInFolderView());
}

// Tests that an app icon is selected when a menu is shown by click.
// TODO(jamescook): Investigate why this is broken with AppListBubble.
TEST_F(AppsGridViewTest, AppIconSelectedWhenMenuIsShown) {
  model_->PopulateApps(1);
  UpdateLayout();
  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.
  auto* generator = GetEventGenerator();
  generator->MoveMouseTo(app->GetBoundsInScreen().CenterPoint());
  generator->PressRightButton();
  EXPECT_TRUE(apps_grid_view_->IsSelectedView(app));

  generator->ReleaseRightButton();
  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 = GetTilesPerPage(0);
  const size_t kPages = 2;
  model_->PopulateApps(kItemsInPage * kPages);
  UpdateLayout();

  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_P(AppsGridViewClamshellTest, ItemViewsDontHaveLayer) {
  size_t kTotalItems = 3;
  model_->PopulateApps(kTotalItems);
  UpdateLayout();

  // 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(AppsGridViewDragTest, DismissWhileDraggingDoesNotCrash) {
  model_->PopulateApps(2);
  UpdateLayout();
  AppListItemView* const item_view = GetItemViewInTopLevelGrid(1);

  // Non-zero animation durations are necessary to make sure we don't miss
  // crashes involving animation delegates. Specifically, `bounds_animator_` had
  // a use after free problem in the past.
  ui::ScopedAnimationDurationScaleMode non_zero_duration_mode(
      ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);

  GetEventGenerator()->MoveMouseTo(
      item_view->GetBoundsInScreen().CenterPoint());
  GetEventGenerator()->PressLeftButton();
  item_view->FireMouseDragTimerForTest();
  GetEventGenerator()->MoveMouseBy(20, 20);

  ASSERT_TRUE(apps_grid_view_->drag_item());
  ASSERT_TRUE(apps_grid_view_->IsDragging());
  ASSERT_EQ(item_view->item(), apps_grid_view_->drag_item());

  GetAppListTestHelper()->Dismiss();
  // No crash
}

TEST_P(AppsGridViewDragTest, DismissWhileDraggingInFolderDoesNotCrash) {
  model_->CreateAndPopulateFolderWithApps(2);
  test_api_->Update();
  test_api_->PressItemAt(0);

  AppListItemView* const item_view =
      GetItemViewInAppsGridAt(1, folder_apps_grid_view());

  // Non-zero animation durations are necessary to make sure we don't miss
  // crashes involving animation delegates. Specifically, `bounds_animator_` had
  // a use after free problem in the past.
  ui::ScopedAnimationDurationScaleMode non_zero_duration_mode(
      ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);

  GetEventGenerator()->MoveMouseTo(
      item_view->GetBoundsInScreen().CenterPoint());
  GetEventGenerator()->PressLeftButton();
  item_view->FireMouseDragTimerForTest();
  GetEventGenerator()->MoveMouseBy(20, 20);

  ASSERT_TRUE(folder_apps_grid_view()->drag_item());
  ASSERT_TRUE(folder_apps_grid_view()->IsDragging());
  ASSERT_EQ(item_view->item(), folder_apps_grid_view()->drag_item());

  GetAppListTestHelper()->Dismiss();
  // No crash
}

TEST_P(AppsGridViewDragTest, ItemViewsHaveLayerDuringDrag) {
  size_t kTotalItems = 3;
  model_->PopulateApps(kTotalItems);
  UpdateLayout();
  InitiateDragForItemAtCurrentPageAt(AppsGridView::MOUSE, 0, 1,
                                     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(AppsGridViewDragTest, ItemViewsDontHaveLayerAfterDrag) {
  size_t kTotalItems = 3;
  model_->PopulateApps(kTotalItems);
  UpdateLayout();
  InitiateDragForItemAtCurrentPageAt(AppsGridView::MOUSE, 0, 1,
                                     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(AppsGridViewDragTest, MouseDragItemIntoFolder) {
  size_t kTotalItems = 3;
  model_->PopulateApps(kTotalItems);
  UpdateLayout();
  InitiateDragForItemAtCurrentPageAt(AppsGridView::MOUSE, 0, 1,
                                     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());

  EXPECT_EQ(is_productivity_launcher_enabled_,
            GetAppListTestHelper()->IsInFolderView());
  if (is_productivity_launcher_enabled_) {
    EXPECT_EQ(folder_item, app_list_folder_view_->folder_item());
    EXPECT_TRUE(app_list_folder_view_->folder_header_view()
                    ->GetFolderNameViewForTest()
                    ->HasFocus());
  }
}

TEST_P(AppsGridViewDragTest, MouseDragSecondItemIntoFolder) {
  AppListFolderItem* folder_item = model_->CreateAndPopulateFolderWithApps(2);
  model_->PopulateApps(1);
  UpdateLayout();
  InitiateDragForItemAtCurrentPageAt(AppsGridView::MOUSE, 0, 1,
                                     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());
  EXPECT_FALSE(GetAppListTestHelper()->IsInFolderView());
}

TEST_P(AppsGridViewDragTest, DragIconAnimatesAfterDragToFolder) {
  model_->CreateAndPopulateFolderWithApps(2);
  model_->PopulateApps(1);
  UpdateLayout();

  ui::ScopedAnimationDurationScaleMode non_zero_duration_mode(
      ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);

  InitiateDragForItemAtCurrentPageAt(AppsGridView::MOUSE, 0, 1,
                                     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*/);

  ui::Layer* drag_icon_layer = test_api_->GetDragIconLayer();
  ASSERT_TRUE(drag_icon_layer);
  ASSERT_TRUE(drag_icon_layer->GetAnimator()->is_animating());
  EXPECT_FALSE(GetAppListTestHelper()->IsInFolderView());

  LayerAnimationStoppedWaiter animation_waiter;
  animation_waiter.Wait(drag_icon_layer);
  EXPECT_FALSE(GetAppListTestHelper()->IsInFolderView());
}

TEST_P(AppsGridViewDragTest, DragIconHiddenImmediatelyWhenGridHides) {
  model_->CreateAndPopulateFolderWithApps(2);
  model_->PopulateApps(1);
  UpdateLayout();

  ui::ScopedAnimationDurationScaleMode non_zero_duration_mode(
      ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);

  InitiateDragForItemAtCurrentPageAt(AppsGridView::MOUSE, 0, 1,
                                     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*/);

  // Start typing to close the apps page, and open search results.
  GetEventGenerator()->GestureTapAt(
      search_box_view_->GetBoundsInScreen().CenterPoint());
  GetEventGenerator()->PressAndReleaseKey(ui::VKEY_A);

  if (is_productivity_launcher_enabled_) {
    ASSERT_TRUE(GetAppListTestHelper()->GetBubbleSearchPage()->GetVisible());
  } else {
    ASSERT_TRUE(GetAppListTestHelper()
                    ->GetFullscreenSearchResultPageView()
                    ->GetVisible());
  }

  // Verify the drag icon is hidden immediately.
  EXPECT_FALSE(test_api_->GetDragIconLayer());
  EXPECT_FALSE(apps_grid_view_->drag_item());
  EXPECT_FALSE(apps_grid_view_->IsDragging());
}

TEST_P(AppsGridViewDragTest, DragIconAnimatesAfterDragToCreateFolder) {
  model_->PopulateApps(3);
  UpdateLayout();

  ui::ScopedAnimationDurationScaleMode non_zero_duration_mode(
      ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);

  InitiateDragForItemAtCurrentPageAt(AppsGridView::MOUSE, 0, 1,
                                     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*/);

  ui::Layer* drag_icon_layer = test_api_->GetDragIconLayer();
  ASSERT_TRUE(drag_icon_layer);
  ASSERT_TRUE(drag_icon_layer->GetAnimator()->is_animating());
  EXPECT_FALSE(GetAppListTestHelper()->IsInFolderView());

  LayerAnimationStoppedWaiter animation_waiter;
  animation_waiter.Wait(drag_icon_layer);
  EXPECT_EQ(is_productivity_launcher_enabled_,
            GetAppListTestHelper()->IsInFolderView());
}

TEST_P(AppsGridViewDragTest, FolderNotOpenedIfGridHidesDuringIconDrop) {
  model_->PopulateApps(3);
  UpdateLayout();

  ui::ScopedAnimationDurationScaleMode non_zero_duration_mode(
      ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);

  InitiateDragForItemAtCurrentPageAt(AppsGridView::MOUSE, 0, 1,
                                     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*/);

  ui::Layer* drag_icon_layer = test_api_->GetDragIconLayer();
  ASSERT_TRUE(drag_icon_layer);
  ASSERT_TRUE(drag_icon_layer->GetAnimator()->is_animating());
  EXPECT_FALSE(GetAppListTestHelper()->IsInFolderView());

  // Start typing to close the apps page, and open search results - verify the
  // folder does not get opened, and that the icon drop animation gets canceled.
  GetEventGenerator()->GestureTapAt(
      search_box_view_->GetBoundsInScreen().CenterPoint());
  GetEventGenerator()->PressAndReleaseKey(ui::VKEY_A);

  if (is_productivity_launcher_enabled_) {
    ASSERT_TRUE(GetAppListTestHelper()->GetBubbleSearchPage()->GetVisible());
  } else {
    ASSERT_TRUE(GetAppListTestHelper()
                    ->GetFullscreenSearchResultPageView()
                    ->GetVisible());
  }

  EXPECT_FALSE(test_api_->GetDragIconLayer());
  EXPECT_FALSE(GetAppListTestHelper()->IsInFolderView());
}

TEST_P(AppsGridViewClamshellTest, CheckFolderWithMultiplePagesContents) {
  // Creates a folder item.
  const size_t kTotalItems = kMaxItemsPerFolderPage;
  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());
  // Productivity launcher uses scrollable folders, not paged.
  if (!features::IsProductivityLauncherEnabled()) {
    EXPECT_EQ(16, AppsGridViewTestApi(folder_apps_grid_view()).TilesPerPage(0));
    EXPECT_EQ(1, GetTotalPages(folder_apps_grid_view()));
    EXPECT_EQ(0, GetSelectedPage(folder_apps_grid_view()));
  }
  EXPECT_TRUE(folder_apps_grid_view()->IsInFolder());
}

TEST_P(AppsGridViewDragTest, MouseDragItemOutOfFolder) {
  // Creates a folder item.
  const size_t kTotalItems = kMaxItemsPerFolderPage;
  AppListFolderItem* folder_item =
      model_->CreateAndPopulateFolderWithApps(kTotalItems);
  test_api_->Update();
  test_api_->PressItemAt(0);
  AppsGridViewTestApi folder_grid_test_api(folder_apps_grid_view());
  // Drag the first folder child out of the folder.
  AppListItemView* drag_view = InitiateDragForItemAtCurrentPageAt(
      AppsGridView::MOUSE, 0, 0, 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());

  // 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();
  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());
  EXPECT_FALSE(GetAppListTestHelper()->IsInFolderView());
}

TEST_P(AppsGridViewDragTest, DragIconAnimatesAfterDragOutOfFolder) {
  model_->CreateAndPopulateFolderWithApps(5);
  test_api_->Update();
  test_api_->PressItemAt(0);

  ui::ScopedAnimationDurationScaleMode non_zero_duration_mode(
      ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);

  // Drag the first folder child out of the folder.
  AppListItemView* drag_view = InitiateDragForItemAtCurrentPageAt(
      AppsGridView::MOUSE, 0, 0, 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());

  // 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();
  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*/);

  ui::Layer* drag_icon_layer = test_api_->GetDragIconLayer();
  ASSERT_TRUE(drag_icon_layer);
  EXPECT_TRUE(drag_icon_layer->GetAnimator()->is_animating());
}

TEST_P(AppsGridViewDragTest, DragIconAnimatesAfterDragToAnotherFolder) {
  model_->CreateAndPopulateFolderWithApps(5);
  model_->CreateAndPopulateFolderWithApps(5);
  test_api_->Update();
  test_api_->PressItemAt(0);

  ui::ScopedAnimationDurationScaleMode non_zero_duration_mode(
      ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);

  // Drag the first folder child out of the folder.
  AppListItemView* drag_view = InitiateDragForItemAtCurrentPageAt(
      AppsGridView::MOUSE, 0, 0, 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());

  // Calculate the coordinates for the drop point.
  gfx::Point drop_point = GetItemRectOnCurrentPageAt(0, 1).CenterPoint();
  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*/);

  ui::Layer* drag_icon_layer = test_api_->GetDragIconLayer();
  ASSERT_TRUE(drag_icon_layer);
  ASSERT_TRUE(drag_icon_layer->GetAnimator()->is_animating());
  EXPECT_FALSE(GetAppListTestHelper()->IsInFolderView());

  LayerAnimationStoppedWaiter animation_waiter;
  animation_waiter.Wait(drag_icon_layer);
  EXPECT_FALSE(GetAppListTestHelper()->IsInFolderView());
}

TEST_P(AppsGridViewDragTest,
       DragIconAnimatesAfterDragThatDeletesOriginalFolder) {
  model_->PopulateApps(2);
  model_->CreateSingleItemFolder("folder_id", "item_id");
  test_api_->Update();
  test_api_->PressItemAt(2);

  ui::ScopedAnimationDurationScaleMode non_zero_duration_mode(
      ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);

  // Drag the only folder child out of the folder.
  AppListItemView* drag_view = InitiateDragForItemAtCurrentPageAt(
      AppsGridView::MOUSE, 0, 0, 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());

  // Calculate the coordinates for the drop point. Note that we we are dropping
  // into the app list view not the folder view. The (0,3) spot is empty.
  gfx::Point drop_point = GetItemRectOnCurrentPageAt(0, 3).CenterPoint();
  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*/);

  ui::Layer* drag_icon_layer = test_api_->GetDragIconLayer();
  ASSERT_TRUE(drag_icon_layer);
  EXPECT_TRUE(drag_icon_layer->GetAnimator()->is_animating());
}

TEST_P(AppsGridViewDragTest, DragIconAnimatesAfterReorderDrag) {
  model_->PopulateApps(3);
  test_api_->Update();

  ui::ScopedAnimationDurationScaleMode non_zero_duration_mode(
      ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);

  // Drag the first item to an empty slot in the grid.
  InitiateDragForItemAtCurrentPageAt(AppsGridView::MOUSE, 0, 0,
                                     apps_grid_view_);
  gfx::Point drop_point = GetItemRectOnCurrentPageAt(0, 3).CenterPoint();
  UpdateDrag(AppsGridView::MOUSE, drop_point, apps_grid_view_, 5 /*steps*/);
  EndDrag(apps_grid_view_, false /*cancel*/);

  ui::Layer* drag_icon_layer = test_api_->GetDragIconLayer();
  ASSERT_TRUE(drag_icon_layer);
  EXPECT_TRUE(drag_icon_layer->GetAnimator()->is_animating());
}

TEST_F(AppsGridViewNonBubbleTest, SwitchPageFolderItem) {
  // ProductivityLauncher does not use paged folders.
  ASSERT_FALSE(features::IsProductivityLauncherEnabled());

  // Creates a folder item with enough views to have a second page.
  const size_t kTotalItems = kMaxItemsPerFolderPage + 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, GetSelectedPage(folder_apps_grid_view()));
  EXPECT_EQ(4, folder_apps_grid_view()->cols());
  EXPECT_EQ(16, AppsGridViewTestApi(folder_apps_grid_view()).TilesPerPage(0));
  EXPECT_TRUE(folder_apps_grid_view()->IsInFolder());
}

TEST_P(AppsGridViewDragNonBubbleTest, MouseDragItemOutOfFolderSecondPage) {
  // ProductivityLauncher does not use paged folders.
  ASSERT_FALSE(features::IsProductivityLauncherEnabled());

  // Creates a folder item with enough views to have a second page.
  const size_t kTotalItems = kMaxItemsPerFolderPage + 1;
  AppListFolderItem* folder_item =
      model_->CreateAndPopulateFolderWithApps(kTotalItems);
  test_api_->Update();
  test_api_->PressItemAt(0);
  // Switch to second page.
  AnimateFolderViewPageFlip(1);
  // Drag the first folder child on the second page out of the folder.
  AppListItemView* drag_view = InitiateDragForItemAtCurrentPageAt(
      AppsGridView::MOUSE, 0, 0, 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. The (0,1) spot is empty.
  gfx::Point drop_point = GetItemRectOnCurrentPageAt(0, 1).CenterPoint();
  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());
  EXPECT_FALSE(GetAppListTestHelper()->IsInFolderView());
}

TEST_P(AppsGridViewDragNonBubbleTest, MouseDropItemFromFolderSecondPage) {
  // ProductivityLauncher does not use paged folders.
  ASSERT_FALSE(features::IsProductivityLauncherEnabled());

  // Creates a folder item with enough views to have a second page.
  const size_t kTotalItems = kMaxItemsPerFolderPage + 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(0) - 2);
  AppsGridViewTestApi folder_grid_test_api(folder_apps_grid_view());

  // Drag the first folder child on the second page out of the folder.
  AppListItemView* drag_view = InitiateDragForItemAtCurrentPageAt(
      AppsGridView::MOUSE, 0, 0, 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::Rect drop_tile_bounds = GetItemRectOnCurrentPageAt(0, 0);
  gfx::Point drop_point = is_rtl_ ? drop_tile_bounds.left_center()
                                  : drop_tile_bounds.right_center();
  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());
  EXPECT_FALSE(GetAppListTestHelper()->IsInFolderView());
}

TEST_P(AppsGridViewDragTest, MouseDragMaxItemsInFolder) {
  // Create and add an almost full folder.
  const size_t kTotalItems = kMaxItemsInFolder - 1;
  AppListFolderItem* folder_item =
      model_->CreateAndPopulateFolderWithApps(kTotalItems);
  ASSERT_FALSE(folder_item->IsFolderFull());
  // Create and add another item.
  model_->PopulateAppWithId(kTotalItems);
  UpdateLayout();
  InitiateDragForItemAtCurrentPageAt(AppsGridView::MOUSE, 0, 1,
                                     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(kTotalItems + 1, folder_item->ChildItemCount());
  EXPECT_TRUE(folder_item->IsFolderFull());
  EXPECT_FALSE(GetAppListTestHelper()->IsInFolderView());
}

TEST_P(AppsGridViewDragTest, MouseDragExceedMaxItemsInFolder) {
  // Create and add a full folder.
  AppListFolderItem* folder_item =
      model_->CreateAndPopulateFolderWithApps(kMaxItemsInFolder);
  EXPECT_TRUE(folder_item->IsFolderFull());

  // Create and add another 2 item.
  model_->PopulateAppWithId(kMaxItemsInFolder + 1);
  InitiateDragForItemAtCurrentPageAt(AppsGridView::MOUSE, 0, 1,
                                     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(kMaxItemsInFolder, folder_item->ChildItemCount());
  EXPECT_TRUE(folder_item->IsFolderFull());
}

TEST_P(AppsGridViewDragTest, MouseDragMovement) {
  // Create and add a full folder.
  model_->CreateAndPopulateFolderWithApps(kMaxItemsInFolder);
  // Create and add another item.
  model_->PopulateAppWithId(kMaxItemsInFolder);
  UpdateLayout();
  AppListItemView* folder_view =
      GetItemViewForPoint(GetItemRectOnCurrentPageAt(0, 0).CenterPoint());
  // Drag the new item to the left so that the grid reorders.
  InitiateDragForItemAtCurrentPageAt(AppsGridView::MOUSE, 0, 1,
                                     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(AppsGridViewDragTest, MouseDragMaxItemsInFolderWithMovement) {
  // Create and add a full folder.
  model_->CreateAndPopulateFolderWithApps(kMaxItemsInFolder);
  AppListFolderItem* folder_item = static_cast<AppListFolderItem*>(
      model_->top_level_item_list()->item_at(0));
  // Create and add another item.
  model_->PopulateAppWithId(kMaxItemsInFolder);
  // Drag the new item to the left so that the grid reorders.
  AppListItemView* dragged_view = InitiateDragForItemAtCurrentPageAt(
      AppsGridView::MOUSE, 0, 1, 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(kMaxItemsInFolder, 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(AppsGridViewDragTest, MouseDragItemReorderBeforeFolderDropPoint) {
  model_->PopulateApps(2);
  UpdateLayout();
  InitiateDragForItemAtCurrentPageAt(AppsGridView::MOUSE, 0, 1,
                                     apps_grid_view_);

  gfx::Point to = GetItemRectOnCurrentPageAt(0, 1).CenterPoint();
  int half_tile_width = std::abs(GetItemRectOnCurrentPageAt(0, 1).x() -
                                 GetItemRectOnCurrentPageAt(0, 0).x()) /
                        2;
  gfx::Vector2d drag_vector(-half_tile_width - 4, 0);
  // Flip drag vector in rtl.
  if (is_rtl_)
    drag_vector.set_x(-drag_vector.x());

  // Drag left but stop before the folder dropping circle.
  UpdateDrag(AppsGridView::MOUSE, to + 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(AppsGridViewDragTest, MouseDragItemReorderAfterFolderDropPoint) {
  model_->PopulateApps(2);
  UpdateLayout();
  InitiateDragForItemAtCurrentPageAt(AppsGridView::MOUSE, 0, 1,
                                     apps_grid_view_);

  gfx::Point to = GetItemRectOnCurrentPageAt(0, 1).CenterPoint();
  int half_tile_width = std::abs(GetItemRectOnCurrentPageAt(0, 1).x() -
                                 GetItemRectOnCurrentPageAt(0, 0).x()) /
                        2;
  gfx::Vector2d drag_vector(
      -2 * half_tile_width -
          GetAppListConfig()->folder_dropping_circle_radius() - 4,
      0);
  // Flip drag vector in rtl.
  if (is_rtl_)
    drag_vector.set_x(-drag_vector.x());

  // Drag left, past the folder dropping circle.
  UpdateDrag(AppsGridView::MOUSE, to + 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(AppsGridViewDragTest, 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);
  UpdateLayout();
  InitiateDragForItemAtCurrentPageAt(AppsGridView::MOUSE, 0, 1,
                                     apps_grid_view_);

  gfx::Point to = GetItemRectOnCurrentPageAt(0, 1).CenterPoint();
  int half_tile_width = std::abs(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);
  // Flip drag vector in rtl.
  if (is_rtl_)
    drag_vector.set_x(-drag_vector.x());

  // Drag down, between apps 5 and 6. The gap should open up, making space for
  // app 1 in the bottom left.
  UpdateDrag(AppsGridView::MOUSE, to + 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(AppsGridViewDragTest, 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);
  UpdateLayout();
  InitiateDragForItemAtCurrentPageAt(AppsGridView::MOUSE, 1, 0,
                                     apps_grid_view_);

  gfx::Point to = GetItemRectOnCurrentPageAt(1, 0).CenterPoint();
  int half_tile_width = std::abs(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);
  // Flip drag vector in rtl.
  if (is_rtl_)
    drag_vector.set_x(-drag_vector.x());

  // Drag up, between apps 0 and 2. The gap should open up, making space for app
  // 1 in the top right.
  UpdateDrag(AppsGridView::MOUSE, to + 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(AppsGridViewDragTest, 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);
  UpdateLayout();
  InitiateDragForItemAtCurrentPageAt(AppsGridView::MOUSE, 0, 1,
                                     apps_grid_view_);

  gfx::Point to = GetItemRectOnCurrentPageAt(0, 1).CenterPoint();
  int half_tile_width = std::abs(GetItemRectOnCurrentPageAt(0, 1).x() -
                                 GetItemRectOnCurrentPageAt(0, 0).x()) /
                        2;
  int tile_height = GetItemRectOnCurrentPageAt(1, 0).y() -
                    GetItemRectOnCurrentPageAt(0, 0).y();
  // Drag over by half a tile and down by one tile. This ends the drag to the
  // right of the last item.
  gfx::Vector2d drag_vector(half_tile_width, tile_height);
  // Flip drag vector in rtl.
  if (is_rtl_)
    drag_vector.set_x(-drag_vector.x());

  UpdateDrag(AppsGridView::MOUSE, to + 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(AppsGridViewDragTest, MouseDragFolderOverItemReorder) {
  size_t kTotalItems = 2;
  AppListFolderItem* folder_item =
      model_->CreateAndPopulateFolderWithApps(kTotalItems);
  model_->PopulateAppWithId(kTotalItems);
  InitiateDragForItemAtCurrentPageAt(AppsGridView::MOUSE, 0, 0,
                                     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(AppsGridViewDragTest, MouseDragWithCancelKeepsOrder) {
  size_t kTotalItems = 2;
  model_->PopulateApps(kTotalItems);
  InitiateDragForItemAtCurrentPageAt(AppsGridView::MOUSE, 0, 0,
                                     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(AppsGridViewDragTest, MouseDragWithDeleteItemKeepsOrder) {
  size_t kTotalItems = 3;
  model_->PopulateApps(kTotalItems);
  InitiateDragForItemAtCurrentPageAt(AppsGridView::MOUSE, 0, 0,
                                     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(AppsGridViewDragTest, MouseDragWithAddItemKeepsOrder) {
  size_t kTotalItems = 2;
  model_->PopulateApps(kTotalItems);
  InitiateDragForItemAtCurrentPageAt(AppsGridView::MOUSE, 0, 0,
                                     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_P(AppsGridViewClamshellAndTabletTest, MoveItemInModelPastEndOfList) {
  model_->PopulateApps(20);
  apps_grid_view_->GetWidget()->LayoutRootViewIfNecessary();

  // 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_P(AppsGridViewClamshellAndTabletTest,
       ControlArrowSwapsAppsWithinSamePage) {
  model_->PopulateApps(20);
  apps_grid_view_->GetWidget()->LayoutRootViewIfNecessary();

  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_P(AppsGridViewClamshellAndTabletTest, ControlArrowRecordsHistogramBasic) {
  base::HistogramTester histogram_tester;
  model_->PopulateApps(20);
  apps_grid_view_->GetWidget()->LayoutRootViewIfNecessary();

  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(GetItemMoveTypeHistogramName(), 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(GetItemMoveTypeHistogramName(), 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(GetItemMoveTypeHistogramName(), 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(GetItemMoveTypeHistogramName(), 6, 4);
}

// Test that histograms do not record when the keyboard move is a no-op.
TEST_P(AppsGridViewClamshellAndTabletTest,
       ControlArrowDoesNotRecordHistogramWithNoOpMove) {
  base::HistogramTester histogram_tester;
  model_->PopulateApps(20);
  apps_grid_view_->GetWidget()->LayoutRootViewIfNecessary();

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

  // Make 2 no-op moves and one successful move from 0,0 and 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(GetItemMoveTypeHistogramName(), 6, 1);
}

// Tests that an item is scrolled to visible position if moved to initially
// invisible grid slot, and that histograms for a long keyboard sequence move
// gets recorded only once.
TEST_P(AppsGridViewClamshellAndTabletTest,
       ControlArrowDownwardMoveSequenceToSlotNotInitiallyVisible) {
  base::HistogramTester histogram_tester;
  model_->PopulateApps(40);
  apps_grid_view_->GetWidget()->LayoutRootViewIfNecessary();

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

  auto app_list_item_view_visible = [this](const views::View* view) -> bool {
    return apps_grid_view_->GetWidget()->GetWindowBoundsInScreen().Contains(
        view->GetBoundsInScreen());
  };

  // The test will repeatedly move an item down until the target slot is in a
  // position that was initially not visible (either on different apps grid
  // page, or clipped withing scrollable apps grid).
  // Find the target row:
  int first_hidden_row = 0;
  while (true) {
    const views::View* first_item_in_row =
        GetItemViewInTopLevelGrid(first_hidden_row * apps_grid_view_->cols());
    ASSERT_TRUE(first_item_in_row);
    if (!app_list_item_view_visible(first_item_in_row))
      break;
    ++first_hidden_row;
  }

  // Make that a series of moves when the control key is left pressed and expect
  // one histogram is recorded.
  for (int i = 0; i < first_hidden_row; ++i) {
    SimulateKeyPress(ui::VKEY_DOWN, ui::EF_CONTROL_DOWN);
    SimulateKeyReleased(ui::VKEY_DOWN, ui::EF_CONTROL_DOWN);
  }
  SimulateKeyReleased(ui::VKEY_DOWN, ui::EF_NONE);

  // Verify that the view is visible at the end of the move.
  EXPECT_TRUE(app_list_item_view_visible(moving_item));

  histogram_tester.ExpectBucketCount(GetItemMoveTypeHistogramName(), 6, 1);
}

// Tests that moving an app down when it is directly below a gap results in a
// swap with the closest item.
TEST_P(AppsGridViewClamshellAndTabletTest, 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_P(AppsGridViewTabletTest, ControlArrowSwapsBetweenFullPages) {
  const int kPages = 3;
  model_->PopulateApps(GetTilesPerPage(0) + (kPages - 1) * GetTilesPerPage(1));
  apps_grid_view_->UpdatePagedViewStructure();

  // 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, GetTilesPerPage(0) - apps_grid_view_->cols() + 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(0, false /*animate*/);
    const GridIndex moved_view_index(
        0, GetTilesPerPage(0) - apps_grid_view_->cols() + 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, GetTilesPerPage(0) - 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(is_rtl_ ? ui::VKEY_LEFT : 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(is_rtl_ ? ui::VKEY_RIGHT : 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_P(AppsGridViewClamshellAndTabletTest,
       ControlArrowDownAndRightCreatesNewPage) {
  base::HistogramTester histogram_tester;
  const int kFirstPageSize = paged_apps_grid_view_ ? GetTilesPerPage(0) : 20;
  model_->PopulateApps(kFirstPageSize);

  // Focus the last item on the page.
  AppListItemView* moving_item = GetItemViewInTopLevelGrid(kFirstPageSize - 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);

  bool expect_page_creation = !is_productivity_launcher_enabled_;
  histogram_tester.ExpectBucketCount("Apps.AppListPageSwitcherSource", 7,
                                     expect_page_creation ? 1 : 0);

  if (expect_page_creation) {
    EXPECT_EQ(moving_item, test_api_->GetViewAtIndex(GridIndex(1, 0)));
  } else {
    EXPECT_EQ(moving_item,
              test_api_->GetViewAtIndex(GridIndex(0, kFirstPageSize - 1)));
  }
  EXPECT_EQ(kFirstPageSize - (expect_page_creation ? 1 : 0),
            test_api_->AppsOnPage(0));

  if (paged_apps_grid_view_) {
    EXPECT_EQ(expect_page_creation ? 1 : 0,
              GetPaginationModel()->selected_page());
    EXPECT_EQ(expect_page_creation ? 2 : 1,
              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,
                                     expect_page_creation ? 2 : 0);

  // 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(expect_page_creation ? nullptr : moving_item,
            test_api_->GetViewAtIndex(GridIndex(0, kFirstPageSize - 1)));
  if (expect_page_creation) {
    EXPECT_EQ(moving_item, test_api_->GetViewAtIndex(GridIndex(1, 0)));
  } else {
    EXPECT_EQ(moving_item,
              test_api_->GetViewAtIndex(GridIndex(0, kFirstPageSize - 1)));
  }
  EXPECT_EQ(kFirstPageSize - (expect_page_creation ? 1 : 0),
            test_api_->AppsOnPage(0));
  EXPECT_EQ(expect_page_creation ? 1 : 0, test_api_->AppsOnPage(1));
  if (paged_apps_grid_view_) {
    EXPECT_EQ(expect_page_creation ? 1 : 0,
              GetPaginationModel()->selected_page());
    EXPECT_EQ(expect_page_creation ? 2 : 1,
              GetPaginationModel()->total_pages());
  }
  histogram_tester.ExpectBucketCount("Apps.AppListPageSwitcherSource", 7,
                                     expect_page_creation ? 3 : 0);
}

// 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(0));
  AppListItemView* moving_item =
      GetItemViewInTopLevelGrid(GetTilesPerPage(0) - 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_P(AppsGridViewClamshellAndTabletTest,
       ControlArrowDownOnLastAppOnLastPage) {
  base::HistogramTester histogram_tester;
  const int kItemCount = paged_apps_grid_view_ ? GetTilesPerPage(0) + 1 : 21;
  model_->PopulateApps(kItemCount);
  AppListItemView* moving_item = GetItemViewInTopLevelGrid(kItemCount - 1);
  apps_grid_view_->GetFocusManager()->SetFocusedView(moving_item);
  if (paged_apps_grid_view_) {
    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, 0);
  histogram_tester.ExpectBucketCount("Apps.AppListAppMovingType", 6, 0);
  histogram_tester.ExpectBucketCount("Apps.AppListBubbleAppMovingType", 6, 0);
  if (paged_apps_grid_view_) {
    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, 0);
  histogram_tester.ExpectBucketCount("Apps.AppListAppMovingType", 6, 0);
  histogram_tester.ExpectBucketCount("Apps.AppListBubbleAppMovingType", 6, 0);
  if (paged_apps_grid_view_) {
    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(0));
  AppListItemView* moving_item =
      GetItemViewInTopLevelGrid(GetTilesPerPage(0) - 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_P(AppsGridViewClamshellAndTabletTest, ControlShiftArrowFoldersItemBasic) {
  base::HistogramTester histogram_tester;
  model_->PopulateApps(3 * apps_grid_view_->cols());
  UpdateLayout();
  // 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();

  ui::test::EventGenerator* const event_generator = GetEventGenerator();
  // Press an arrow key to engage keyboard traversal in fullscreen launcher.
  event_generator->PressAndReleaseKey(ui::VKEY_DOWN);

  // Focus first item, and folder it.
  apps_grid_view_->GetFocusManager()->SetFocusedView(first_item);
  event_generator->PressAndReleaseKey(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.
  AppListItemView* new_folder = GetItemViewInTopLevelGrid(0);
  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(GetItemMoveTypeHistogramName(),
                                     kMoveByKeyboardIntoFolder, 1);

  // With productivity launcher enabled, the folder is expected to get opened
  // after creation.
  EXPECT_EQ(!is_productivity_launcher_enabled_,
            apps_grid_view_->IsSelectedView(new_folder));
  EXPECT_EQ(is_productivity_launcher_enabled_,
            GetAppListTestHelper()->IsInFolderView());
  if (is_productivity_launcher_enabled_) {
    EXPECT_EQ(folder_item, app_list_folder_view_->folder_item());
    EXPECT_TRUE(app_list_folder_view_->folder_header_view()
                    ->GetFolderNameViewForTest()
                    ->HasFocus());

    // Close the folder.
    event_generator->PressAndReleaseKey(ui::VKEY_UP);
    event_generator->PressAndReleaseKey(ui::VKEY_ESCAPE);
    EXPECT_FALSE(GetAppListTestHelper()->IsInFolderView());
  }
  ASSERT_TRUE(new_folder->HasFocus());
  ASSERT_TRUE(apps_grid_view_->IsSelectedView(new_folder));

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

  EXPECT_TRUE(apps_grid_view_->IsSelectedView(new_folder));
  EXPECT_TRUE(new_folder->HasFocus());
  EXPECT_EQ(2u, folder_item->ChildItemCount());
  histogram_tester.ExpectBucketCount(GetItemMoveTypeHistogramName(),
                                     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));

  event_generator->PressAndReleaseKey(ui::VKEY_LEFT,
                                      ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN);

  EXPECT_FALSE(GetAppListTestHelper()->IsInFolderView());
  EXPECT_TRUE(apps_grid_view_->IsSelectedView(new_folder));
  EXPECT_TRUE(new_folder->HasFocus());
  EXPECT_EQ(3u, folder_item->ChildItemCount());
  histogram_tester.ExpectBucketCount(GetItemMoveTypeHistogramName(),
                                     kMoveByKeyboardIntoFolder, 2);

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

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

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

  EXPECT_FALSE(GetAppListTestHelper()->IsInFolderView());
  EXPECT_TRUE(apps_grid_view_->IsSelectedView(new_folder));
  EXPECT_TRUE(new_folder->HasFocus());
  EXPECT_EQ(5u, folder_item->ChildItemCount());
  histogram_tester.ExpectBucketCount(GetItemMoveTypeHistogramName(),
                                     kMoveByKeyboardIntoFolder, 4);
}

// Tests that foldering an item that is on a different page fails.
TEST_P(AppsGridViewTabletTest, ControlShiftArrowFailsToFolderAcrossPages) {
  model_->PopulateApps(GetTilesPerPage(0) + GetTilesPerPage(1));
  UpdateLayout();

  // 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, GetTilesPerPage(0) - apps_grid_view_->cols() + 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, GetTilesPerPage(0) - 1);
  AppListItemView* attempted_folder_view =
      test_api_->GetViewAtIndex(moved_view_index);

  SimulateKeyPress(is_rtl_ ? ui::VKEY_LEFT : 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(is_rtl_ ? ui::VKEY_RIGHT : 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());
  }
}

TEST_P(AppsGridViewClamshellAndTabletTest,
       KeyboardReparentFromFolderInLastVisibleSlot) {
  // Create grid with a folder on the last slot in a page (or for scrollable
  // grid, the last slot in the page with enough items that the slot is
  // initially not in the visible part of the grid).
  const int kTopLevelItemCount = paged_apps_grid_view_
                                     ? GetTilesPerPage(0) + GetTilesPerPage(1)
                                     : apps_grid_view_->cols() * 8;
  model_->PopulateApps(kTopLevelItemCount - 1);
  const AppListFolderItem* folder_item =
      model_->CreateAndPopulateFolderWithApps(3);
  const std::string folder_id = folder_item->id();
  apps_grid_view_->UpdatePagedViewStructure();
  UpdateLayout();

  AppListItemView* folder_view = apps_grid_view_->view_model()->view_at(
      apps_grid_view_->view_model()->view_size() - 1);
  ASSERT_TRUE(folder_view->is_folder());
  EXPECT_FALSE(apps_grid_view_->GetWidget()->GetWindowBoundsInScreen().Contains(
      folder_view->GetBoundsInScreen()));

  folder_view->RequestFocus();
  EXPECT_TRUE(apps_grid_view_->GetWidget()->GetWindowBoundsInScreen().Contains(
      folder_view->GetBoundsInScreen()));

  // Open the folder.
  ui::test::EventGenerator* const event_generator = GetEventGenerator();
  event_generator->PressAndReleaseKey(ui::VKEY_RETURN);
  ASSERT_TRUE(GetAppListTestHelper()->IsInFolderView());

  const AppListItemView* reparented_item_view =
      folder_apps_grid_view()->view_model()->view_at(0);
  ASSERT_TRUE(reparented_item_view);
  ASSERT_TRUE(reparented_item_view->item());

  std::string reparented_item_id = reparented_item_view->item()->id();
  EXPECT_EQ(base::StringPrintf("Item %d", kTopLevelItemCount - 1),
            reparented_item_id);
  ASSERT_TRUE(reparented_item_view->HasFocus());

  // Reparent the item to the slot after the folder view, which should be the
  // last spot in the grid.
  const ui::KeyboardCode forward_key = is_rtl_ ? ui::VKEY_LEFT : ui::VKEY_RIGHT;
  event_generator->PressAndReleaseKey(forward_key,
                                      ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN);
  ASSERT_FALSE(GetAppListTestHelper()->IsInFolderView());
  ASSERT_EQ(folder_item, model_->FindItem(folder_id));
  EXPECT_EQ(2u, folder_item->ChildItemCount());

  const AppListItemView* last_top_level_item_view =
      apps_grid_view_->view_model()->view_at(
          apps_grid_view_->view_model()->view_size() - 1);
  // Verify the view is within visible grid bounds, and that it has focus.
  EXPECT_EQ(reparented_item_id, last_top_level_item_view->item()->id());
  EXPECT_TRUE(apps_grid_view_->GetWidget()->GetWindowBoundsInScreen().Contains(
      last_top_level_item_view->GetBoundsInScreen()));
  EXPECT_TRUE(last_top_level_item_view->HasFocus());

  // In paged apps grid, the item should have been moved to a new page.
  if (paged_apps_grid_view_) {
    EXPECT_EQ(2, GetPaginationModel()->selected_page());
    EXPECT_EQ(3, GetPaginationModel()->total_pages());
  }
}

TEST_P(AppsGridViewClamshellAndTabletTest,
       KeyboardReparentFromFolderInLastVisibleSlotUsingDownKey) {
  // Create grid with a folder on the last slot in a page (or for scrollable
  // grid, the last slot in the page with enough items that the slot is
  // initially not in the visible part of the grid).
  const int kTopLevelItemCount = paged_apps_grid_view_
                                     ? GetTilesPerPage(0) + GetTilesPerPage(1)
                                     : apps_grid_view_->cols() * 8;
  model_->PopulateApps(kTopLevelItemCount - 1);
  const AppListFolderItem* folder_item =
      model_->CreateAndPopulateFolderWithApps(3);
  const std::string folder_id = folder_item->id();
  apps_grid_view_->UpdatePagedViewStructure();
  UpdateLayout();

  AppListItemView* folder_view = apps_grid_view_->view_model()->view_at(
      apps_grid_view_->view_model()->view_size() - 1);
  ASSERT_TRUE(folder_view->is_folder());
  EXPECT_FALSE(apps_grid_view_->GetWidget()->GetWindowBoundsInScreen().Contains(
      folder_view->GetBoundsInScreen()));

  folder_view->RequestFocus();
  EXPECT_TRUE(apps_grid_view_->GetWidget()->GetWindowBoundsInScreen().Contains(
      folder_view->GetBoundsInScreen()));

  // Open the folder.
  ui::test::EventGenerator* const event_generator = GetEventGenerator();
  event_generator->PressAndReleaseKey(ui::VKEY_RETURN);
  ASSERT_TRUE(GetAppListTestHelper()->IsInFolderView());

  const AppListItemView* reparented_item_view =
      folder_apps_grid_view()->view_model()->view_at(0);
  ASSERT_TRUE(reparented_item_view);
  ASSERT_TRUE(reparented_item_view->item());

  std::string reparented_item_id = reparented_item_view->item()->id();
  EXPECT_EQ(base::StringPrintf("Item %d", kTopLevelItemCount - 1),
            reparented_item_id);
  ASSERT_TRUE(reparented_item_view->HasFocus());

  // Reparent the item to the slot after the folder view, which should be the
  // last spot in the grid.
  event_generator->PressAndReleaseKey(ui::VKEY_DOWN,
                                      ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN);
  ASSERT_FALSE(GetAppListTestHelper()->IsInFolderView());
  ASSERT_EQ(folder_item, model_->FindItem(folder_id));
  EXPECT_EQ(2u, folder_item->ChildItemCount());

  const AppListItemView* last_top_level_item_view =
      apps_grid_view_->view_model()->view_at(
          apps_grid_view_->view_model()->view_size() - 1);
  // Verify the view is within visible grid bounds, and that it has focus.
  EXPECT_EQ(reparented_item_id, last_top_level_item_view->item()->id());
  EXPECT_TRUE(apps_grid_view_->GetWidget()->GetWindowBoundsInScreen().Contains(
      last_top_level_item_view->GetBoundsInScreen()));
  EXPECT_TRUE(last_top_level_item_view->HasFocus());

  // In paged apps grid, the item should have been moved to a new page.
  if (paged_apps_grid_view_) {
    EXPECT_EQ(2, GetPaginationModel()->selected_page());
    EXPECT_EQ(3, GetPaginationModel()->total_pages());
  }
}

TEST_P(AppsGridViewTabletTest,
       KeyboardReparentFromFolderPrefersLeavingMovedItemOnCurrentPage) {
  model_->PopulateApps(GetTilesPerPage(0) - 2);
  const AppListFolderItem* folder_item =
      model_->CreateAndPopulateFolderWithApps(3);
  model_->PopulateApps(GetTilesPerPage(1));
  const std::string folder_id = folder_item->id();
  apps_grid_view_->UpdatePagedViewStructure();
  UpdateLayout();

  AppListItemView* folder_view =
      test_api_->GetViewAtIndex(GridIndex(0, GetTilesPerPage(0) - 2));
  ASSERT_TRUE(folder_view->is_folder());
  folder_view->RequestFocus();

  // Open the folder.
  ui::test::EventGenerator* const event_generator = GetEventGenerator();
  event_generator->PressAndReleaseKey(ui::VKEY_RETURN);
  ASSERT_TRUE(GetAppListTestHelper()->IsInFolderView());

  const AppListItemView* reparented_item_view =
      folder_apps_grid_view()->view_model()->view_at(0);
  ASSERT_TRUE(reparented_item_view);
  ASSERT_TRUE(reparented_item_view->item());

  std::string reparented_item_id = reparented_item_view->item()->id();
  EXPECT_EQ(base::StringPrintf("Item %d", GetTilesPerPage(0) - 2),
            reparented_item_id);
  ASSERT_TRUE(reparented_item_view->HasFocus());

  // Reparent the item to the slot after the folder view, which should be the
  // last spot in the grid.
  event_generator->PressAndReleaseKey(ui::VKEY_DOWN,
                                      ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN);
  ASSERT_FALSE(GetAppListTestHelper()->IsInFolderView());
  ASSERT_EQ(folder_item, model_->FindItem(folder_id));
  EXPECT_EQ(2u, folder_item->ChildItemCount());

  const AppListItemView* last_item_on_first_page =
      test_api_->GetViewAtIndex(GridIndex(0, GetTilesPerPage(0) - 1));
  // Verify the view is within visible grid bounds, and that it has focus.
  EXPECT_EQ(reparented_item_id, last_item_on_first_page->item()->id());
  EXPECT_TRUE(apps_grid_view_->GetWidget()->GetWindowBoundsInScreen().Contains(
      last_item_on_first_page->GetBoundsInScreen()));
  EXPECT_TRUE(last_item_on_first_page->HasFocus());

  EXPECT_EQ(0, GetPaginationModel()->selected_page());
  EXPECT_EQ(2, GetPaginationModel()->total_pages());
}

// Tests that foldering the item on the last slot of a page doesn't crash.
TEST_P(AppsGridViewClamshellAndTabletTest,
       ControlShiftArrowFolderLastItemOnPage) {
  const int kNumberOfApps = 4;
  model_->PopulateApps(kNumberOfApps);
  UpdateLayout();
  // 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();

  ui::test::EventGenerator* const event_generator = GetEventGenerator();
  // Press an arrow key to engage keyboard traversal in fullscreen launcher.
  event_generator->PressAndReleaseKey(ui::VKEY_DOWN);

  apps_grid_view_->GetFocusManager()->SetFocusedView(moving_item);
  event_generator->PressAndReleaseKey(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);
  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));

  // With productivity launcher enabled, the folder is expected to get opened
  // after creation.
  EXPECT_EQ(!is_productivity_launcher_enabled_,
            apps_grid_view_->IsSelectedView(new_folder));
  EXPECT_EQ(is_productivity_launcher_enabled_,
            GetAppListTestHelper()->IsInFolderView());
  if (is_productivity_launcher_enabled_) {
    EXPECT_EQ(folder_item, app_list_folder_view_->folder_item());
    EXPECT_TRUE(app_list_folder_view_->folder_header_view()
                    ->GetFolderNameViewForTest()
                    ->HasFocus());

    // Close the folder.
    event_generator->PressAndReleaseKey(ui::VKEY_UP);
    event_generator->PressAndReleaseKey(ui::VKEY_ESCAPE);
    EXPECT_FALSE(GetAppListTestHelper()->IsInFolderView());
  }
  EXPECT_TRUE(new_folder->HasFocus());
  EXPECT_TRUE(apps_grid_view_->IsSelectedView(new_folder));
}

TEST_P(AppsGridViewTabletTest, TouchDragFlipToNextPage) {
  ASSERT_TRUE(paged_apps_grid_view_);

  // Create 3 full pages of apps.
  model_->PopulateApps(GetTilesPerPage(0) + GetTilesPerPage(1) +
                       GetTilesPerPage(2));
  UpdateLayout();

  const gfx::Rect apps_grid_bounds = paged_apps_grid_view_->GetLocalBounds();
  // Drag an item to the bottom to start flipping pages.
  page_flip_waiter_->Reset();
  InitiateDragForItemAtCurrentPageAt(AppsGridView::TOUCH, 0, 0,
                                     paged_apps_grid_view_);
  gfx::Point apps_grid_bottom_center =
      gfx::Point(apps_grid_bounds.width() / 2, apps_grid_bounds.bottom() - 1);
  UpdateDrag(AppsGridView::TOUCH, apps_grid_bottom_center,
             paged_apps_grid_view_, 5 /*steps*/);
  while (HasPendingPageFlip(paged_apps_grid_view_)) {
    page_flip_waiter_->Wait();
  }

  if (features::IsProductivityLauncherEnabled()) {
    // A new page cannot be created or flipped to with the ProductivityLauncher
    // flag enabled.
    EXPECT_EQ("1,2", page_flip_waiter_->selected_pages());
    EXPECT_EQ(2, GetPaginationModel()->selected_page());
  } else {
    // 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());
  }
  // The drag is centered relative to the app item icon bounds, not the whole
  // app item view.
  gfx::Vector2d icon_offset(0,
                            GetAppListConfig()->grid_icon_bottom_padding() / 2);
  EXPECT_EQ(apps_grid_bottom_center - icon_offset, GetDragIconCenter());

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

TEST_P(AppsGridViewTabletTest, DragAcrossPagesToTheLastSlot) {
  ASSERT_TRUE(paged_apps_grid_view_);

  // Create a full page and a partially full second page.
  model_->PopulateApps(GetTilesPerPage(0) + 3);
  apps_grid_view_->UpdatePagedViewStructure();
  UpdateLayout();

  // Drag an item from the first page to the last existing slot on the next
  // page.
  const views::ViewModelT<AppListItemView>* view_model =
      apps_grid_view_->view_model();
  AppListItemView* dragged_view = view_model->view_at(0);
  AppListItemView* original_first_item_on_second_page =
      view_model->view_at(GetTilesPerPage(0));

  auto* generator = GetEventGenerator();

  // Initiate drag.
  generator->MoveMouseTo(dragged_view->GetBoundsInScreen().CenterPoint());
  generator->PressLeftButton();
  dragged_view->FireMouseDragTimerForTest();
  generator->MoveMouseBy(10, 10);

  // Drag the item to launcher page flip zone, and flip the launcher to the
  // second page.
  generator->MoveMouseTo(
      paged_apps_grid_view_->GetBoundsInScreen().bottom_center() +
      gfx::Vector2d(0, -1));
  ASSERT_TRUE(HasPendingPageFlip(paged_apps_grid_view_));

  // Task to move mouse from the page flip area after the page gets flipped, to
  // prevent subseuquent page flips.
  PostPageFlipTask task(GetPaginationModel(), base::BindLambdaForTesting([&]() {
                          generator->MoveMouseBy(0, -50);
                          generator->MoveMouseBy(0, -50);
                        }));

  page_flip_waiter_->Wait();

  // Ensure that the reoreder timer ran, and that any views on the second page
  // that should have been moved to the first page have done so.
  ASSERT_TRUE(paged_apps_grid_view_->reorder_timer_for_test()->IsRunning());
  paged_apps_grid_view_->reorder_timer_for_test()->FireNow();
  test_api_->WaitForItemMoveAnimationDone();

  // Move the item to the first empty slot on the second page.
  gfx::Point empty_slot =
      test_api_->GetItemTileRectAtVisualIndex(1, 3).CenterPoint();
  views::View::ConvertPointToScreen(paged_apps_grid_view_, &empty_slot);
  generator->MoveMouseTo(empty_slot);
  test_api_->WaitForItemMoveAnimationDone();

  if (paged_apps_grid_view_->reorder_timer_for_test()->IsRunning())
    paged_apps_grid_view_->reorder_timer_for_test()->FireNow();
  test_api_->WaitForItemMoveAnimationDone();

  const int expected_final_slot = is_productivity_launcher_enabled_ ? 2 : 3;
  EXPECT_EQ(GridIndex(1, expected_final_slot),
            paged_apps_grid_view_->reorder_placeholder());

  // Verify that the last item in the grid is left of the expected placeholder
  // location.
  const gfx::Rect last_slot_rect =
      GetItemRectOnCurrentPageAt(1, expected_final_slot);
  const views::View* last_view =
      view_model->view_at(view_model->view_size() - 1);
  if (is_rtl_) {
    gfx::Point last_view_left_center_in_grid =
        last_view->GetLocalBounds().left_center();
    views::View::ConvertPointToTarget(last_view, paged_apps_grid_view_,
                                      &last_view_left_center_in_grid);
    EXPECT_GE(last_view_left_center_in_grid.x(), last_slot_rect.right());
  } else {
    gfx::Point last_view_right_center_in_grid =
        last_view->GetLocalBounds().right_center();
    views::View::ConvertPointToTarget(last_view, paged_apps_grid_view_,
                                      &last_view_right_center_in_grid);
    EXPECT_LE(last_view_right_center_in_grid.x(), last_slot_rect.x());
  }

  EndDrag(paged_apps_grid_view_, false);

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

  // Verify that the dragged item was moved to the last slot.
  AppListItemView* last_item_view =
      test_api_->GetViewAtVisualIndex(1, expected_final_slot);
  ASSERT_TRUE(last_item_view);
  EXPECT_EQ(dragged_view->item()->id(), last_item_view->item()->id());

  // For productivity launcher, the first item on second page should have been
  // moved to the first page (to fill up the empty slot left by moving the
  // draggged item away). For non-productivity launcher, the last slot should
  // remain empty.
  AppListItemView* last_item_on_first_page =
      test_api_->GetViewAtVisualIndex(0, GetTilesPerPage(0) - 1);
  ASSERT_EQ(is_productivity_launcher_enabled_, !!last_item_on_first_page);
  if (is_productivity_launcher_enabled_) {
    EXPECT_EQ(original_first_item_on_second_page->item()->id(),
              last_item_on_first_page->item()->id());
  }
}

TEST_P(AppsGridViewTabletTest, DragAcrossPagesToSecondToLastSlot) {
  ASSERT_TRUE(paged_apps_grid_view_);

  // Create a full page and a partially full second page.
  model_->PopulateApps(GetTilesPerPage(0) + 3);
  apps_grid_view_->UpdatePagedViewStructure();
  UpdateLayout();

  const views::ViewModelT<AppListItemView>* view_model =
      apps_grid_view_->view_model();
  AppListItemView* dragged_view = view_model->view_at(0);
  AppListItemView* original_first_item_on_second_page =
      view_model->view_at(GetTilesPerPage(0));

  auto* generator = GetEventGenerator();

  // Initiate drag.
  generator->MoveMouseTo(dragged_view->GetBoundsInScreen().CenterPoint());
  generator->PressLeftButton();
  dragged_view->FireMouseDragTimerForTest();
  generator->MoveMouseBy(10, 10);

  // Drag the item to launcher page flip zone, and flip the launcher to the
  // second page.
  generator->MoveMouseTo(
      paged_apps_grid_view_->GetBoundsInScreen().bottom_center() +
      gfx::Vector2d(0, -1));
  ASSERT_TRUE(HasPendingPageFlip(paged_apps_grid_view_));

  // Task to move mouse from the page flip area after the page gets flipped, to
  // prevent subseuquent page flips.
  PostPageFlipTask task(GetPaginationModel(), base::BindLambdaForTesting([&]() {
                          generator->MoveMouseBy(0, -50);
                          generator->MoveMouseBy(0, -50);
                        }));

  page_flip_waiter_->Wait();

  // Ensure that the reoreder timer ran, and that any views on the second page
  // that should have been moved to the first page have done so.
  ASSERT_TRUE(paged_apps_grid_view_->reorder_timer_for_test()->IsRunning());
  paged_apps_grid_view_->reorder_timer_for_test()->FireNow();
  test_api_->WaitForItemMoveAnimationDone();

  // Move the item between two last slots on the page.
  views::View* last_view = view_model->view_at(view_model->view_size() - 1);
  const gfx::Point last_slot = last_view->GetBoundsInScreen().CenterPoint();
  views::View* second_to_last_view =
      view_model->view_at(view_model->view_size() - 2);
  const gfx::Point second_to_last_slot =
      second_to_last_view->GetBoundsInScreen().CenterPoint();
  const gfx::Point drop_point((last_slot.x() + second_to_last_slot.x()) / 2,
                              last_slot.y());

  generator->MoveMouseTo(drop_point);

  if (paged_apps_grid_view_->reorder_timer_for_test()->IsRunning())
    paged_apps_grid_view_->reorder_timer_for_test()->FireNow();
  test_api_->WaitForItemMoveAnimationDone();

  const int expected_final_slot = is_productivity_launcher_enabled_ ? 1 : 2;
  EXPECT_EQ(GridIndex(1, expected_final_slot),
            paged_apps_grid_view_->reorder_placeholder());

  // Verify that the last item in the grid is right of the expected placeholder
  // location.
  const gfx::Rect target_slot_rect =
      GetItemRectOnCurrentPageAt(1, expected_final_slot);
  if (is_rtl_) {
    gfx::Point last_view_right_center_in_grid =
        last_view->GetLocalBounds().right_center();
    views::View::ConvertPointToTarget(last_view, paged_apps_grid_view_,
                                      &last_view_right_center_in_grid);
    EXPECT_LE(last_view_right_center_in_grid.x(), target_slot_rect.x());
  } else {
    gfx::Point last_view_left_center_in_grid =
        last_view->GetLocalBounds().left_center();
    views::View::ConvertPointToTarget(last_view, paged_apps_grid_view_,
                                      &last_view_left_center_in_grid);
    EXPECT_GE(last_view_left_center_in_grid.x(), target_slot_rect.right());
  }

  // Verify that second to last item in the grid is left of the expected
  // placeholder location.
  if (is_rtl_) {
    gfx::Point second_to_last_view_left_center_in_grid =
        second_to_last_view->GetLocalBounds().left_center();
    views::View::ConvertPointToTarget(second_to_last_view,
                                      paged_apps_grid_view_,
                                      &second_to_last_view_left_center_in_grid);
    EXPECT_GE(second_to_last_view_left_center_in_grid.x(),
              target_slot_rect.right());
  } else {
    gfx::Point second_to_last_view_right_center_in_grid =
        second_to_last_view->GetLocalBounds().right_center();
    views::View::ConvertPointToTarget(
        second_to_last_view, paged_apps_grid_view_,
        &second_to_last_view_right_center_in_grid);
    EXPECT_LE(second_to_last_view_right_center_in_grid.x(),
              target_slot_rect.x());
  }

  generator->ReleaseLeftButton();

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

  // Verify that the dragged item was moved to the target slot.
  AppListItemView* last_item_view =
      test_api_->GetViewAtVisualIndex(1, expected_final_slot);
  ASSERT_TRUE(last_item_view);
  EXPECT_EQ(dragged_view->item()->id(), last_item_view->item()->id());

  // For productivity launcher, the first item on second page should have been
  // moved to the first page (to fill up the empty slot left by moving the
  // draggged item away). For non-productivity launcher, the last slot should
  // remain empty.
  AppListItemView* last_item_on_first_page =
      test_api_->GetViewAtVisualIndex(0, GetTilesPerPage(0) - 1);
  ASSERT_EQ(is_productivity_launcher_enabled_, !!last_item_on_first_page);
  if (is_productivity_launcher_enabled_) {
    EXPECT_EQ(original_first_item_on_second_page->item()->id(),
              last_item_on_first_page->item()->id());
  }
}

TEST_P(AppsGridViewTabletTest,
       UpdatePagingIfPageSizesChangeOverflownLandspaceToPortait) {
  ASSERT_TRUE(paged_apps_grid_view_);

  // Create 2 full pages of apps, and add another app to overflow to third page.
  const int kTotalApps = GetTilesPerPage(0) + GetTilesPerPage(1) + 1;
  model_->PopulateApps(kTotalApps);
  EXPECT_EQ(3, GetPaginationModel()->total_pages());

  // Rotate the screen, and verify that the number of pages decreased if new
  // page structure fit all apps into 2 pages (number of items per page may
  // change between landscape and protrait mode for productivity launcher).
  UpdateDisplay("1024x768/r");

  EXPECT_EQ(kTotalApps <= GetTilesPerPage(0) + GetTilesPerPage(1) ? 2 : 3,
            GetPaginationModel()->total_pages());
}

TEST_P(AppsGridViewTabletTest,
       UpdatePagingIfPageSizesChangeUnderflowLandspaceToPortait) {
  ASSERT_TRUE(paged_apps_grid_view_);

  // Create 2 full pages of apps, and add another app to overflow to third page.
  const int kTotalApps = GetTilesPerPage(0) + GetTilesPerPage(1) - 1;
  model_->PopulateApps(kTotalApps);
  EXPECT_EQ(2, GetPaginationModel()->total_pages());

  // Rotate the screen, and verify that the number of pages increased if new
  // page structure does not fit all apps into 2 pages (number of items per page
  // may change between landscape and protrait mode for productivity launcher).
  UpdateDisplay("1024x768/r");

  EXPECT_EQ(kTotalApps <= GetTilesPerPage(0) + GetTilesPerPage(1) ? 2 : 3,
            GetPaginationModel()->total_pages());
}

TEST_P(AppsGridViewTabletTest,
       UpdatePagingIfPageSizesChangeOverflownPortraitToLandcape) {
  ASSERT_TRUE(paged_apps_grid_view_);
  UpdateDisplay("1024x768/r");

  // Create 2 full pages of apps, and add another app to overflow to third page.
  const int kTotalApps = GetTilesPerPage(0) + GetTilesPerPage(1) + 1;
  model_->PopulateApps(kTotalApps);
  EXPECT_EQ(3, GetPaginationModel()->total_pages());

  // Rotate the screen, and verify that the number of pages decreased if new
  // page structure fit all apps into 2 pages (number of items per page may
  // change between landscape and protrait mode for productivity launcher).
  UpdateDisplay("1024x768");

  EXPECT_EQ(kTotalApps <= GetTilesPerPage(0) + GetTilesPerPage(1) ? 2 : 3,
            GetPaginationModel()->total_pages());
}

TEST_P(AppsGridViewTabletTest,
       UpdatePagingIfPageSizesChangeUnderflowPortraitToLandscape) {
  ASSERT_TRUE(paged_apps_grid_view_);
  UpdateDisplay("1024x768/r");

  // Create 2 full pages of apps, and add another app to overflow to third page.
  const int kTotalApps = GetTilesPerPage(0) + GetTilesPerPage(1) - 1;
  model_->PopulateApps(kTotalApps);
  EXPECT_EQ(2, GetPaginationModel()->total_pages());

  // Rotate the screen, and verify that the number of pages increaesed if new
  // page structure fits all apps into 2 pages (which may be the case if
  // productivity launcher is enabled, in which case protrait mode grid has more
  // items per page than landscape UI).
  UpdateDisplay("1024x768");

  EXPECT_EQ(kTotalApps <= GetTilesPerPage(0) + GetTilesPerPage(1) ? 2 : 3,
            GetPaginationModel()->total_pages());
}

TEST_P(AppsGridViewTabletTest, TouchDragFlipToPreviousPage) {
  ASSERT_TRUE(paged_apps_grid_view_);

  // Create 3 full pages of apps.
  model_->PopulateApps(GetTilesPerPage(0) + GetTilesPerPage(1) +
                       GetTilesPerPage(2));
  // Select the last page.
  GetPaginationModel()->SelectPage(2, /*animate=*/false);

  // Drag an item to the top to start flipping pages.
  page_flip_waiter_->Reset();
  InitiateDragForItemAtCurrentPageAt(AppsGridView::TOUCH, 0, 0,
                                     paged_apps_grid_view_);
  gfx::Point apps_grid_top_center(
      paged_apps_grid_view_->GetLocalBounds().width() / 2, 0);
  UpdateDrag(AppsGridView::TOUCH, apps_grid_top_center, paged_apps_grid_view_,
             5 /*steps*/);
  while (HasPendingPageFlip(paged_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());
  // The drag is centered relative to the app item icon bounds, not the whole
  // app item view.
  gfx::Vector2d icon_offset(0,
                            GetAppListConfig()->grid_icon_bottom_padding() / 2);
  EXPECT_EQ(apps_grid_top_center - icon_offset, GetDragIconCenter());

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

TEST_P(AppsGridViewDragTest, CancelDragDoesNotReorderItems) {
  const int kTotalItems = 4;
  model_->PopulateApps(kTotalItems);
  ASSERT_EQ(std::string("Item 0,Item 1,Item 2,Item 3"),
            model_->GetModelContent());

  // Starts a mouse drag and then cancels it.
  InitiateDragForItemAtCurrentPageAt(AppsGridView::MOUSE, 0, 0,
                                     apps_grid_view_);
  const gfx::Point to = GetItemRectOnCurrentPageAt(0, 2).CenterPoint();
  UpdateDrag(AppsGridView::MOUSE, to, apps_grid_view_);
  EndDrag(apps_grid_view_, /*cancel=*/true);

  // Model is not changed.
  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);
  UpdateLayout();
  EXPECT_TRUE(search_box_view_->search_box()->HasFocus());
  EXPECT_FALSE(apps_grid_view_->view_model()->view_at(0)->HasFocus());
}

// Test focus change during dragging an item. (See https://crbug.com/834682)
TEST_P(AppsGridViewDragTest, FocusOfDraggedViewDuringDrag) {
  model_->PopulateApps(1);
  UpdateLayout();
  AppListItemView* item_view = InitiateDragForItemAtCurrentPageAt(
      AppsGridView::MOUSE, 0, 0, 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_view_->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(AppsGridViewDragTest, FocusOfDraggedViewAfterDrag) {
  model_->PopulateApps(1);
  UpdateLayout();
  auto* item_view = apps_grid_view_->view_model()->view_at(0);
  InitiateDragForItemAtCurrentPageAt(AppsGridView::MOUSE, 0, 0,
                                     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*/);

  if (features::IsProductivityLauncherEnabled()) {
    // ProductivityLauncher keeps focus on the search box after drags.
    EXPECT_TRUE(search_box_view_->search_box()->HasFocus());
    EXPECT_FALSE(item_view->HasFocus());
  } else {
    EXPECT_FALSE(search_box_view_->search_box()->HasFocus());
    EXPECT_TRUE(item_view->HasFocus());
  }
}

// Verify the dragged item's focus after the item is dragged from a folder with
// a single items.
TEST_P(AppsGridViewDragTest, FocusOfReparentedDragViewWithFolderDeleted) {
  // Creates a folder item with two items.
  model_->CreateAndPopulateFolderWithApps(2);
  model_->PopulateApps(1);
  test_api_->Update();

  // Leave the dragged item as a single folder child.
  model_->DeleteItem("Item 1");
  // One folder and one app. Therefore the top level view count is 2.
  EXPECT_EQ(2, apps_grid_view_->view_model()->view_size());

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

  // Drag the first folder child out of the folder.
  InitiateDragForItemAtCurrentPageAt(AppsGridView::MOUSE, 0, 0,
                                     folder_apps_grid_view());
  gfx::Point point_outside_folder =
      app_list_folder_view()->GetLocalBounds().bottom_center() +
      gfx::Vector2d(10, 10);
  UpdateDrag(AppsGridView::MOUSE, point_outside_folder, folder_apps_grid_view(),
             /*steps=*/10);

  // 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 the item in (0,2) spot is the root apps grid. The spot is expected to
  // be empty.
  gfx::Point drop_point = GetItemRectOnCurrentPageAt(0, 2).CenterPoint();
  views::View::ConvertPointToTarget(apps_grid_view_, folder_apps_grid_view(),
                                    &drop_point);
  UpdateDrag(AppsGridView::MOUSE, drop_point, folder_apps_grid_view(),
             /*steps=*/5);
  BoundsChangeCounter counter(GetItemViewInTopLevelGrid(1));
  EndDrag(folder_apps_grid_view(), /*cancel=*/false);

  // The folder should be deleted. The first item should be Item 2, the second
  // item should be Item 0.
  EXPECT_EQ(2, apps_grid_view_->view_model()->view_size());
  EXPECT_EQ("Item 2", GetItemViewInTopLevelGrid(0)->item()->id());
  EXPECT_EQ("Item 0", GetItemViewInTopLevelGrid(1)->item()->id());

  AppListItemView* const dragged_view = GetItemViewInTopLevelGrid(1);
  if (features::IsProductivityLauncherEnabled()) {
    // Verify that Item 2's bounds do not change after calling `EndDrag()`.
    EXPECT_EQ(0, counter.bounds_change_count());

    // ProductivityLauncher keeps focus on the search box after drags.
    EXPECT_TRUE(search_box_view_->search_box()->HasFocus());
    EXPECT_FALSE(dragged_view->HasFocus());
  } else {
    // Verify that Item 2's bounds change once after calling `EndDrag()` due to
    // ending the cardified state.
    EXPECT_EQ(1, counter.bounds_change_count());

    // The dragged item is focused but is not selected.
    EXPECT_TRUE(dragged_view->HasFocus());
    EXPECT_FALSE(apps_grid_view_->has_selected_view());

    // Press the arrow key. The dragged item is selected now.
    PressAndReleaseKey(ui::VKEY_RIGHT);
    EXPECT_TRUE(dragged_view->HasFocus());
    EXPECT_TRUE(apps_grid_view_->has_selected_view());
    EXPECT_EQ(dragged_view, apps_grid_view_->selected_view());
  }
}

TEST_P(AppsGridViewDragTest, FocusOfReparentedDragViewAfterDrag) {
  // Creates a folder item - the folder size was chosen arbitrarily.
  model_->CreateAndPopulateFolderWithApps(5);
  // Add more apps to the root apps grid.
  model_->PopulateApps(2);
  test_api_->Update();

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

  // Drag the first folder child out of the folder.
  InitiateDragForItemAtCurrentPageAt(AppsGridView::MOUSE, 0, 0,
                                     folder_apps_grid_view());
  gfx::Point point_outside_folder =
      app_list_folder_view()->GetLocalBounds().bottom_center() +
      gfx::Vector2d(10, 10);
  UpdateDrag(AppsGridView::MOUSE, point_outside_folder, folder_apps_grid_view(),
             /*steps=*/10);

  // 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 the item in (0,3) spot is the root apps grid. The spot is expected to
  // be empty.
  gfx::Point drop_point = GetItemRectOnCurrentPageAt(0, 3).CenterPoint();
  views::View::ConvertPointToTarget(apps_grid_view_, folder_apps_grid_view(),
                                    &drop_point);
  UpdateDrag(AppsGridView::MOUSE, drop_point, folder_apps_grid_view(),
             /*steps=*/5);
  EndDrag(folder_apps_grid_view(), /*cancel=*/false);

  AppListItemView* const item_view = GetItemViewInTopLevelGrid(3);
  EXPECT_EQ("Item 0", item_view->item()->id());

  if (features::IsProductivityLauncherEnabled()) {
    // ProductivityLauncher keeps focus on the search box after drags.
    EXPECT_TRUE(search_box_view_->search_box()->HasFocus());
    EXPECT_FALSE(item_view->HasFocus());
  } else {
    EXPECT_TRUE(item_view->HasFocus());
  }
}

TEST_P(AppsGridViewDragTest, DragAndPinItemToShelf) {
  model_->PopulateApps(2);
  UpdateLayout();

  AppListItemView* const item_view = GetItemViewInTopLevelGrid(1);

  auto* generator = GetEventGenerator();
  generator->MoveMouseTo(item_view->GetBoundsInScreen().CenterPoint());
  generator->PressLeftButton();
  item_view->FireMouseDragTimerForTest();
  generator->MoveMouseBy(10, 10);

  // Verify that item drag has started.
  ASSERT_TRUE(apps_grid_view_->drag_item());
  ASSERT_TRUE(apps_grid_view_->IsDragging());
  ASSERT_EQ(item_view->item(), apps_grid_view_->drag_item());

  // Shelf should start handling the drag if it moves within its bounds.
  auto* shelf_view = GetPrimaryShelf()->GetShelfViewForTesting();
  generator->MoveMouseTo(shelf_view->GetBoundsInScreen().left_center());
  ASSERT_TRUE(apps_grid_view_->FireDragToShelfTimerForTest());

  EXPECT_EQ("Item 1", shelf_view->drag_and_drop_shelf_id().app_id);

  // Releasing drag over shelf should pin the dragged app.
  generator->ReleaseLeftButton();
  EXPECT_TRUE(ShelfModel::Get()->IsAppPinned("Item 1"));
  EXPECT_EQ("Item 1", ShelfModel::Get()->items()[0].id.app_id);
}

TEST_P(AppsGridViewDragTest, DragAndPinNotInitiallyVisibleItemToShelf) {
  // Add more apps to the root apps grid.
  model_->PopulateApps(50);
  UpdateLayout();

  // Select item that is not withing the default apps grid view bounds.
  AppListItemView* const item_view = GetItemViewInTopLevelGrid(40);
  ASSERT_FALSE(apps_grid_view_->GetWidget()->GetWindowBoundsInScreen().Contains(
      item_view->GetBoundsInScreen()));

  // Focusing and scrolling view to visible should ensure it becomes visible
  // both in scrollable and paged apps grid.
  item_view->RequestFocus();
  item_view->ScrollViewToVisible();

  ASSERT_TRUE(apps_grid_view_->GetWidget()->GetWindowBoundsInScreen().Contains(
      item_view->GetBoundsInScreen()));

  auto* generator = GetEventGenerator();
  generator->MoveMouseTo(item_view->GetBoundsInScreen().CenterPoint());
  generator->PressLeftButton();
  item_view->FireMouseDragTimerForTest();
  generator->MoveMouseBy(10, 10);

  // Verify app list item drag has started.
  ASSERT_TRUE(apps_grid_view_->drag_item());
  ASSERT_TRUE(apps_grid_view_->IsDragging());
  ASSERT_EQ(item_view->item(), apps_grid_view_->drag_item());

  // Shelf should start handling the drag if it moves within its bounds.
  auto* shelf_view = GetPrimaryShelf()->GetShelfViewForTesting();
  generator->MoveMouseTo(shelf_view->GetBoundsInScreen().left_center());
  ASSERT_TRUE(apps_grid_view_->FireDragToShelfTimerForTest());

  EXPECT_EQ("Item 40", shelf_view->drag_and_drop_shelf_id().app_id);

  // Releasing drag over shelf should pin the dragged app.
  generator->ReleaseLeftButton();
  EXPECT_TRUE(ShelfModel::Get()->IsAppPinned("Item 40"));
  EXPECT_EQ("Item 40", ShelfModel::Get()->items()[0].id.app_id);
}

TEST_P(AppsGridViewDragTest, DragItemToAndFromShelf) {
  model_->PopulateApps(2);
  UpdateLayout();

  AppListItemView* const item_view = GetItemViewInTopLevelGrid(1);

  auto* generator = GetEventGenerator();
  generator->MoveMouseTo(item_view->GetBoundsInScreen().CenterPoint());
  generator->PressLeftButton();
  item_view->FireMouseDragTimerForTest();
  generator->MoveMouseBy(10, 10);

  // Verify app list item drag has started.
  ASSERT_TRUE(apps_grid_view_->drag_item());
  ASSERT_TRUE(apps_grid_view_->IsDragging());
  ASSERT_EQ(item_view->item(), apps_grid_view_->drag_item());

  // Shelf should start handling the drag if it moves within its bounds.
  auto* shelf_view = GetPrimaryShelf()->GetShelfViewForTesting();
  generator->MoveMouseTo(shelf_view->GetBoundsInScreen().left_center());
  ASSERT_TRUE(apps_grid_view_->FireDragToShelfTimerForTest());
  EXPECT_EQ("Item 1", shelf_view->drag_and_drop_shelf_id().app_id);

  // Move the app away from shelf, and verify the app doesn't get pinned when
  // the drag ends.
  generator->MoveMouseTo(apps_grid_view_->GetBoundsInScreen().origin());
  generator->ReleaseLeftButton();

  EXPECT_FALSE(ShelfModel::Get()->IsAppPinned("Item 1"));
  EXPECT_TRUE(ShelfModel::Get()->items().empty());
}

TEST_P(AppsGridViewDragTest, DragAndPinItemFromFolderToShelf) {
  // Creates a folder item - the folder size was chosen arbitrarily.
  model_->CreateAndPopulateFolderWithApps(5);
  // Add more apps to the root apps grid.
  model_->PopulateApps(2);
  test_api_->Update();

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

  AppListItemView* const item_view =
      GetItemViewInAppsGridAt(1, folder_apps_grid_view());

  auto* generator = GetEventGenerator();
  generator->MoveMouseTo(item_view->GetBoundsInScreen().CenterPoint());
  generator->PressLeftButton();
  item_view->FireMouseDragTimerForTest();
  generator->MoveMouseBy(10, 10);

  // Verify app list item drag has started.
  ASSERT_TRUE(folder_apps_grid_view()->drag_item());
  ASSERT_TRUE(folder_apps_grid_view()->IsDragging());
  ASSERT_EQ(item_view->item(), folder_apps_grid_view()->drag_item());

  generator->MoveMouseTo(
      app_list_folder_view()->GetBoundsInScreen().right_center() +
      gfx::Vector2d(20, 0));

  // Fire the reparent timer that should be started when an item is dragged out
  // of folder bounds.
  ASSERT_TRUE(folder_apps_grid_view()->FireFolderItemReparentTimerForTest());

  // Shelf should start handling the drag if it moves within its bounds.
  auto* shelf_view = GetPrimaryShelf()->GetShelfViewForTesting();
  generator->MoveMouseTo(shelf_view->GetBoundsInScreen().left_center());
  ASSERT_TRUE(folder_apps_grid_view()->FireDragToShelfTimerForTest());

  EXPECT_EQ("Item 1", shelf_view->drag_and_drop_shelf_id().app_id);

  // Releasing drag over shelf should pin the dragged app.
  generator->ReleaseLeftButton();
  EXPECT_TRUE(ShelfModel::Get()->IsAppPinned("Item 1"));
  EXPECT_EQ("Item 1", ShelfModel::Get()->items()[0].id.app_id);
}

TEST_P(AppsGridViewDragTest, DragAndPinNotInitiallyVisibleFolderItemToShelf) {
  model_->CreateAndPopulateFolderWithApps(2 * kMaxItemsPerFolderPage);
  UpdateLayout();

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

  // Select item that is not within the initial folder view bounds.
  AppListItemView* const item_view =
      GetItemViewInAppsGridAt(30, folder_apps_grid_view());

  ASSERT_FALSE(app_list_folder_view()->GetBoundsInScreen().Contains(
      item_view->GetBoundsInScreen()));

  // Focusing and scrolling view to visible should ensure it becomes visible
  // both in scrollable and paged apps grid.
  item_view->RequestFocus();
  item_view->ScrollViewToVisible();

  ASSERT_TRUE(app_list_folder_view()->GetBoundsInScreen().Contains(
      item_view->GetBoundsInScreen()));

  auto* generator = GetEventGenerator();
  generator->MoveMouseTo(item_view->GetBoundsInScreen().CenterPoint());
  generator->PressLeftButton();
  item_view->FireMouseDragTimerForTest();
  generator->MoveMouseBy(10, 10);

  // Verify app list item drag has started.
  ASSERT_TRUE(folder_apps_grid_view()->drag_item());
  ASSERT_TRUE(folder_apps_grid_view()->IsDragging());
  ASSERT_EQ(item_view->item(), folder_apps_grid_view()->drag_item());

  generator->MoveMouseTo(
      app_list_folder_view()->GetBoundsInScreen().right_center() +
      gfx::Vector2d(20, 0));

  // Fire the reparent timer that should be started when an item is dragged out
  // of folder bounds.
  ASSERT_TRUE(folder_apps_grid_view()->FireFolderItemReparentTimerForTest());

  // Shelf should start handling the drag if it moves within its bounds.
  auto* shelf_view = GetPrimaryShelf()->GetShelfViewForTesting();
  generator->MoveMouseTo(shelf_view->GetBoundsInScreen().left_center());
  ASSERT_TRUE(folder_apps_grid_view()->FireDragToShelfTimerForTest());

  EXPECT_EQ("Item 30", shelf_view->drag_and_drop_shelf_id().app_id);

  // Releasing drag over shelf should pin the dragged app.
  generator->ReleaseLeftButton();

  EXPECT_TRUE(ShelfModel::Get()->IsAppPinned("Item 30"));
  EXPECT_EQ("Item 30", ShelfModel::Get()->items()[0].id.app_id);
}

TEST_P(AppsGridViewDragTest, DragAnItemFromFolderToAndFromShelf) {
  // Creates a folder item - the folder size was chosen arbitrarily.
  model_->CreateAndPopulateFolderWithApps(5);
  // Add more apps to the root apps grid.
  model_->PopulateApps(2);
  UpdateLayout();

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

  AppListItemView* const item_view =
      GetItemViewInAppsGridAt(1, folder_apps_grid_view());

  auto* generator = GetEventGenerator();
  generator->MoveMouseTo(item_view->GetBoundsInScreen().CenterPoint());
  generator->PressLeftButton();
  item_view->FireMouseDragTimerForTest();
  generator->MoveMouseBy(10, 10);

  // Verify app list item drag has started.
  ASSERT_TRUE(folder_apps_grid_view()->drag_item());
  ASSERT_TRUE(folder_apps_grid_view()->IsDragging());
  ASSERT_EQ(item_view->item(), folder_apps_grid_view()->drag_item());

  generator->MoveMouseTo(
      app_list_folder_view()->GetBoundsInScreen().right_center() +
      gfx::Vector2d(20, 0));

  // Fire the reparent timer that should be started when an item is dragged out
  // of folder bounds.
  ASSERT_TRUE(folder_apps_grid_view()->FireFolderItemReparentTimerForTest());

  // Shelf should start handling the drag if it moves within its bounds.
  auto* shelf_view = GetPrimaryShelf()->GetShelfViewForTesting();
  generator->MoveMouseTo(shelf_view->GetBoundsInScreen().left_center());
  ASSERT_TRUE(folder_apps_grid_view()->FireDragToShelfTimerForTest());

  EXPECT_EQ("Item 1", shelf_view->drag_and_drop_shelf_id().app_id);

  // Move the app away from shelf, and verify the app doesn't get pinned when
  // the drag ends.
  generator->MoveMouseTo(apps_grid_view_->GetBoundsInScreen().origin());
  generator->ReleaseLeftButton();

  EXPECT_FALSE(ShelfModel::Get()->IsAppPinned("Item 1"));
  EXPECT_TRUE(ShelfModel::Get()->items().empty());
}

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

  model_->PopulateApps(GetTilesPerPage(0) + 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(0));
  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());

  views::View* scrollable_container = app_list_view_->app_list_main_view()
                                          ->contents_view()
                                          ->apps_container_view()
                                          ->scrollable_container_for_test();
  ASSERT_FALSE(scrollable_container->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(scrollable_container->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(scrollable_container->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 = kMaxItemsPerFolderPage;
  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(16, AppsGridViewTestApi(folder_apps_grid_view()).TilesPerPage(0));
  EXPECT_EQ(1, GetTotalPages(folder_apps_grid_view()));
  EXPECT_EQ(0, GetSelectedPage(folder_apps_grid_view()));
  EXPECT_TRUE(folder_apps_grid_view()->IsInFolder());
}

// This is a NonBubble test because new empty pages cannot be created with the
// ProductivityLauncher feature.
TEST_P(AppsGridViewDragNonBubbleTest, MoveAnItemToNewEmptyPage) {
  const int kApps = 2;
  model_->PopulateApps(kApps);
  const views::ViewModelT<AppListItemView>* view_model =
      apps_grid_view_->view_model();
  InitiateDragForItemAtCurrentPageAt(AppsGridView::MOUSE, 0, 0,
                                     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());
}

// This is a NonBubble test because new empty pages cannot be created with the
// ProductivityLauncher feature.
TEST_P(AppsGridViewDragNonBubbleTest, MoveLastItemToCreateFolderInNextPage) {
  const int kApps = 2;
  model_->PopulateApps(kApps);
  const views::ViewModelT<AppListItemView>* view_model =
      apps_grid_view_->view_model();
  InitiateDragForItemAtCurrentPageAt(AppsGridView::MOUSE, 0, 0,
                                     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);
  InitiateDragForItemAtCurrentPageAt(AppsGridView::MOUSE, 0, 0,
                                     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());
}

// This is a NonBubble test because new empty pages cannot be created with the
// ProductivityLauncher feature.
TEST_P(AppsGridViewDragNonBubbleTest, MoveLastItemForReorderInNextPage) {
  const int kApps = 2;
  model_->PopulateApps(kApps);
  const views::ViewModelT<AppListItemView>* view_model =
      apps_grid_view_->view_model();
  InitiateDragForItemAtCurrentPageAt(AppsGridView::MOUSE, 0, 0,
                                     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);
  InitiateDragForItemAtCurrentPageAt(AppsGridView::MOUSE, 0, 0,
                                     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());
}

// This is a NonBubble test because new empty pages cannot be created with the
// ProductivityLauncher feature.
TEST_P(AppsGridViewDragNonBubbleTest, MoveLastItemToNewEmptyPage) {
  const int kApps = 1;
  model_->PopulateApps(kApps);
  const views::ViewModelT<AppListItemView>* view_model =
      apps_grid_view_->view_model();
  InitiateDragForItemAtCurrentPageAt(AppsGridView::MOUSE, 0, 0,
                                     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);
  InitiateDragForItemAtCurrentPageAt(AppsGridView::MOUSE, 0, 0,
                                     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(0);
  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(AppsGridViewClamshellAndTabletTest, RootGridUpdatesOnModelChange) {
  model_->PopulateApps(2);
  UpdateLayout();

  const views::ViewModelT<AppListItemView>* view_model =
      apps_grid_view_->view_model();
  EXPECT_EQ(2, view_model->view_size());
  TestAppListItemViewIndice();

  // Update the model, and verify the apps grid gets updated.
  auto model_override = std::make_unique<test::AppListTestModel>();
  model_override->PopulateApps(3);
  model_override->CreateAndPopulateFolderWithApps(5);
  model_override->PopulateApps(3);

  auto search_model_override = std::make_unique<SearchModel>();

  Shell::Get()->app_list_controller()->SetActiveModel(
      /*profile_id=*/1, model_override.get(), search_model_override.get());
  UpdateLayout();

  // Verify that the view model size matches the new model.
  EXPECT_EQ(7, view_model->view_size());
  TestAppListItemViewIndice();

  // Verify that clicking an item activates it.
  LeftClickOn(view_model->view_at(0));
  EXPECT_EQ("Item 0", GetTestAppListClient()->activate_item_last_id());

  // Clicking on the folder item transitions to folder view.
  LeftClickOn(view_model->view_at(3));
  EXPECT_TRUE(GetAppListTestHelper()->IsInFolderView());

  ASSERT_EQ(5, folder_apps_grid_view()->view_model()->view_size());

  // Click on an item within the folder.
  LeftClickOn(folder_apps_grid_view()->view_model()->view_at(1));
  EXPECT_EQ("Item 4", GetTestAppListClient()->activate_item_last_id());

  // Switch model to original one, and verify the folder view gets closed.
  Shell::Get()->app_list_controller()->SetActiveModel(
      /*profile_id=*/1, model_.get(), search_model_.get());
  UpdateLayout();
  EXPECT_FALSE(GetAppListTestHelper()->IsInFolderView());
  EXPECT_EQ(2, view_model->view_size());
  TestAppListItemViewIndice();

  LeftClickOn(view_model->view_at(1));
  EXPECT_EQ("Item 1", GetTestAppListClient()->activate_item_last_id());

  Shell::Get()->app_list_controller()->ClearActiveModel();
  EXPECT_EQ(0, view_model->view_size());
}

TEST_P(AppsGridViewClamshellAndTabletTest,
       TouchScrollFromFolderNameDoesNotAffectRootGrid) {
  // Add enough items to the root grid so the launcher becomes paged.
  model_->PopulateApps(1);
  model_->CreateAndPopulateFolderWithApps(5);
  // `GetTilesPerPage()` may return a large number for bubble launcher - ensure
  // the number of test apps is not excessive.
  model_->PopulateApps(std::min(30, GetTilesPerPage(0)));
  UpdateLayout();

  // Open the folder view.
  LeftClickOn(apps_grid_view_->view_model()->view_at(1));
  ASSERT_TRUE(GetAppListTestHelper()->IsInFolderView());

  AppsGridView* const root_grid_view = apps_grid_view_;
  const gfx::Point original_root_grid_origin =
      apps_grid_view_->GetBoundsInScreen().origin();
  const gfx::Point original_first_item_origin =
      apps_grid_view_->view_model()->view_at(0)->GetBoundsInScreen().origin();
  ui::test::ScrollStepCallback verify_grid_bounds = base::BindLambdaForTesting(
      [&](ui::EventType event_type, const gfx::Vector2dF& offset) {
        EXPECT_EQ(original_root_grid_origin,
                  root_grid_view->GetBoundsInScreen().origin());
        EXPECT_EQ(original_first_item_origin, root_grid_view->view_model()
                                                  ->view_at(0)
                                                  ->GetBoundsInScreen()
                                                  .origin());
      });

  // Simulate upward gesture scroll from folder header view, and verify it
  // doesn't affect the root apps grid view location.
  gfx::Point scroll_start = app_list_folder_view_->folder_header_view()
                                ->GetBoundsInScreen()
                                .CenterPoint();
  GetEventGenerator()->GestureScrollSequenceWithCallback(
      scroll_start, scroll_start - gfx::Vector2d(0, 100),
      /*duration=*/base::Milliseconds(50),
      /*steps=*/5, verify_grid_bounds);

  ASSERT_EQ(original_root_grid_origin,
            apps_grid_view_->GetBoundsInScreen().origin());
  ASSERT_EQ(
      original_first_item_origin,
      apps_grid_view_->view_model()->view_at(0)->GetBoundsInScreen().origin());
  ASSERT_TRUE(GetAppListTestHelper()->IsInFolderView());

  // Simulate downward gesture scroll from folder header view, and verify it
  // doesn't affect the root apps grid view location.
  scroll_start = app_list_folder_view_->folder_header_view()
                     ->GetBoundsInScreen()
                     .CenterPoint();
  GetEventGenerator()->GestureScrollSequenceWithCallback(
      scroll_start, scroll_start + gfx::Vector2d(0, 100),
      /*duration=*/base::Milliseconds(50),
      /*steps=*/5, verify_grid_bounds);

  EXPECT_EQ(original_root_grid_origin,
            apps_grid_view_->GetBoundsInScreen().origin());
  EXPECT_EQ(
      original_first_item_origin,
      apps_grid_view_->view_model()->view_at(0)->GetBoundsInScreen().origin());
}

TEST_P(AppsGridViewClamshellAndTabletTest,
       TouchScrollFromFolderGridDoesNotAffectRootGrid) {
  // Add enough items to the root grid so the launcher becomes paged.
  model_->PopulateApps(1);
  model_->CreateAndPopulateFolderWithApps(5);
  // `GetTilesPerPage()` may return a large number for bubble launcher - ensure
  // the number of test apps is not excessive.
  model_->PopulateApps(std::min(30, GetTilesPerPage(0)));
  UpdateLayout();

  // Open the folder view.
  LeftClickOn(apps_grid_view_->view_model()->view_at(1));
  ASSERT_TRUE(GetAppListTestHelper()->IsInFolderView());

  AppsGridView* const root_grid_view = apps_grid_view_;
  const gfx::Point original_root_grid_origin =
      apps_grid_view_->GetBoundsInScreen().origin();
  const gfx::Point original_first_item_origin =
      apps_grid_view_->view_model()->view_at(0)->GetBoundsInScreen().origin();
  ui::test::ScrollStepCallback verify_grid_bounds = base::BindLambdaForTesting(
      [&](ui::EventType event, const gfx::Vector2dF& offset) {
        EXPECT_EQ(original_root_grid_origin,
                  root_grid_view->GetBoundsInScreen().origin());
        EXPECT_EQ(original_first_item_origin, root_grid_view->view_model()
                                                  ->view_at(0)
                                                  ->GetBoundsInScreen()
                                                  .origin());
      });

  // Simulate downward gesture scroll from folder grid (outside any folder app
  // list item view), and verify it doesn't affect the root apps grid view
  // location.
  gfx::Point scroll_start = GetItemViewInAppsGridAt(0, folder_apps_grid_view())
                                ->GetBoundsInScreen()
                                .right_center() +
                            gfx::Vector2d(1, 0);
  GetEventGenerator()->GestureScrollSequenceWithCallback(
      scroll_start, scroll_start - gfx::Vector2d(0, 100),
      /*duration=*/base::Milliseconds(50),
      /*steps=*/5, verify_grid_bounds);

  ASSERT_EQ(original_root_grid_origin,
            apps_grid_view_->GetBoundsInScreen().origin());
  ASSERT_EQ(
      original_first_item_origin,
      apps_grid_view_->view_model()->view_at(0)->GetBoundsInScreen().origin());
  ASSERT_TRUE(GetAppListTestHelper()->IsInFolderView());

  // Simulate downward gesture scroll from folder header view, and verify it
  // doesn't affect the root apps grid view location.
  scroll_start = GetItemViewInAppsGridAt(0, folder_apps_grid_view())
                     ->GetBoundsInScreen()
                     .right_center() +
                 gfx::Vector2d(1, 0);
  GetEventGenerator()->GestureScrollSequenceWithCallback(
      scroll_start, scroll_start + gfx::Vector2d(0, 100),
      /*duration=*/base::Milliseconds(50),
      /*steps=*/5, verify_grid_bounds);

  EXPECT_EQ(original_root_grid_origin,
            apps_grid_view_->GetBoundsInScreen().origin());
  EXPECT_EQ(
      original_first_item_origin,
      apps_grid_view_->view_model()->view_at(0)->GetBoundsInScreen().origin());
}

// This is a NonBubble test because page breaks are ignored with the
// ProductivityLauncher feature.
TEST_P(AppsGridViewDragNonBubbleTest, PageBreakItemAddedAfterDrag) {
  // There are two pages and last item is on second page.
  const int kApps = 2 + GetTilesPerPage(0);
  model_->PopulateApps(kApps);
  GetPaginationModel()->SelectPage(1, false);
  InitiateDragForItemAtCurrentPageAt(AppsGridView::MOUSE, 0, 1,
                                     apps_grid_view_);
  gfx::Rect tile_rect = test_api_->GetItemTileRectAtVisualIndex(0, 0);
  gfx::Point to_in_previous_page =
      is_rtl_ ? tile_rect.right_center() : tile_rect.left_center();

  // 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(0) - 1)
      model_content.append(",PageBreakItem");
  }
  EXPECT_EQ(model_content, model_->GetModelContent());
}

TEST_P(AppsGridViewTabletTest, MoveItemToPreviousFullPage) {
  // There are two pages and last item is on second page.
  const int kApps = 2 + GetTilesPerPage(0);
  model_->PopulateApps(kApps);
  const views::ViewModelT<AppListItemView>* view_model =
      apps_grid_view_->view_model();
  GetPaginationModel()->SelectPage(1, false);
  InitiateDragForItemAtCurrentPageAt(AppsGridView::MOUSE, 0, 1,
                                     apps_grid_view_);

  gfx::Rect tile_rect = test_api_->GetItemTileRectAtVisualIndex(0, 0);
  gfx::Point to_in_previous_page =
      is_rtl_ ? tile_rect.right_center() : tile_rect.left_center();

  // 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(0);
    int slot = i % GetTilesPerPage(0);
    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());
  }
}

// This is a NonBubble test because page breaks are ignored with the
// ProductivityLauncher feature.
TEST_P(AppsGridViewDragNonBubbleTest, MoveItemSubsequentDragKeepPageBreak) {
  // There are two pages and last item is on second page.
  const int kApps = 2 + GetTilesPerPage(0);
  model_->PopulateApps(kApps);
  const views::ViewModelT<AppListItemView>* view_model =
      apps_grid_view_->view_model();
  GetPaginationModel()->SelectPage(1, false);
  InitiateDragForItemAtCurrentPageAt(AppsGridView::MOUSE, 0, 1,
                                     apps_grid_view_);

  gfx::Rect tile_rect = test_api_->GetItemTileRectAtVisualIndex(0, 0);
  gfx::Point to_in_previous_page =
      is_rtl_ ? tile_rect.right_center() : tile_rect.left_center();

  // 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);
  InitiateDragForItemAtCurrentPageAt(AppsGridView::MOUSE, 0, 1,
                                     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(0);
    int slot = i % GetTilesPerPage(0);
    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(0) - 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);
}

// This is a NonBubble test because new empty pages cannot be created with the
// ProductivityLauncher feature.
TEST_P(AppsGridViewDragNonBubbleTest, CreateANewPageByDraggingLogsMetrics) {
  ASSERT_TRUE(paged_apps_grid_view_) << "Only available in tablet mode or when "
                                        "ProductivityLauncher is disabled.";

  base::HistogramTester histogram_tester;
  model_->PopulateApps(2);
  InitiateDragForItemAtCurrentPageAt(AppsGridView::MOUSE, 0, 0,
                                     paged_apps_grid_view_);
  const gfx::Rect apps_grid_bounds = paged_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, paged_apps_grid_view_);
  while (HasPendingPageFlip(paged_apps_grid_view_))
    page_flip_waiter_->Wait();
  EndDrag(paged_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(0));

  // 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) {
  ASSERT_TRUE(paged_apps_grid_view_);

  // Create only one page with two apps.
  model_->PopulateApps(2);

  // Start cardified apps grid.
  InitiateDragForItemAtCurrentPageAt(AppsGridView::TOUCH, 0, 0,
                                     paged_apps_grid_view_);

  EXPECT_TRUE(paged_apps_grid_view_->cardified_state_for_testing());

  const int kExpectedBackgroundCardCount =
      features::IsProductivityLauncherEnabled() ? 1 : 2;
  EXPECT_EQ(kExpectedBackgroundCardCount,
            paged_apps_grid_view_->BackgroundCardCountForTesting());

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

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

  // Enter cardified state.
  InitiateDragForItemAtCurrentPageAt(AppsGridView::TOUCH, 0, 0,
                                     paged_apps_grid_view_);
  ASSERT_TRUE(paged_apps_grid_view_->cardified_state_for_testing());

  const int kExpectedBackgroundCardCount =
      features::IsProductivityLauncherEnabled() ? 2 : 3;
  ASSERT_EQ(kExpectedBackgroundCardCount,
            paged_apps_grid_view_->BackgroundCardCountForTesting());

  // Verify that all items in the current page fit within the background card.
  gfx::Rect background_card_bounds =
      paged_apps_grid_view_->GetBackgroundCardBoundsForTesting(0);
  gfx::Rect clip_rect = paged_apps_grid_view_->GetMirroredRect(
      paged_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(
      GetTilesPerPage(0) / apps_grid_view_->cols() - 1,
      apps_grid_view_->cols() - 1);

  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 screen rotation (r = 90 degrees clockwise).
  UpdateDisplay("1024x768/r");
  app_list_view_->OnParentWindowBoundsChanged();

  ASSERT_TRUE(paged_apps_grid_view_->cardified_state_for_testing());
  ASSERT_EQ(kExpectedBackgroundCardCount,
            paged_apps_grid_view_->BackgroundCardCountForTesting());

  // Verify that all items in the current page fit within the background card.
  background_card_bounds =
      paged_apps_grid_view_->GetBackgroundCardBoundsForTesting(0);
  clip_rect = paged_apps_grid_view_->GetMirroredRect(
      paged_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(
      GetTilesPerPage(0) / apps_grid_view_->cols() - 1,
      apps_grid_view_->cols() - 1);

  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(paged_apps_grid_view_, false /*cancel*/);
  EXPECT_EQ(gfx::Rect(), paged_apps_grid_view_->layer()->clip_rect());
  EXPECT_FALSE(paged_apps_grid_view_->cardified_state_for_testing());
  EXPECT_EQ(0, paged_apps_grid_view_->BackgroundCardCountForTesting());
}

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

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

  // Trigger cardified state again.
  InitiateDragForItemAtCurrentPageAt(AppsGridView::TOUCH, 0, 0,
                                     paged_apps_grid_view_);

  ASSERT_TRUE(paged_apps_grid_view_->cardified_state_for_testing());
  const int kExpectedBackgroundCardCount =
      features::IsProductivityLauncherEnabled() ? 2 : 3;
  ASSERT_EQ(kExpectedBackgroundCardCount,
            paged_apps_grid_view_->BackgroundCardCountForTesting());

  // Verify that all items in the current page fit within the background card.
  gfx::Rect background_card_bounds =
      paged_apps_grid_view_->GetBackgroundCardBoundsForTesting(1);
  gfx::Rect clip_rect = paged_apps_grid_view_->GetMirroredRect(
      paged_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(
      GetTilesPerPage(1) / apps_grid_view_->cols() - 1,
      apps_grid_view_->cols() - 1);

  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 screen rotation (r = 90 degrees clockwise).
  UpdateDisplay("1024x768/r");

  ASSERT_TRUE(paged_apps_grid_view_->cardified_state_for_testing());
  ASSERT_EQ(kExpectedBackgroundCardCount,
            paged_apps_grid_view_->BackgroundCardCountForTesting());

  // Verify that all items in the current page fit within the background card.
  background_card_bounds =
      paged_apps_grid_view_->GetBackgroundCardBoundsForTesting(1);
  clip_rect = paged_apps_grid_view_->GetMirroredRect(
      paged_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(
      GetTilesPerPage(1) / apps_grid_view_->cols() - 1,
      apps_grid_view_->cols() - 1);

  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(paged_apps_grid_view_, false /*cancel*/);
  EXPECT_EQ(gfx::Rect(), paged_apps_grid_view_->layer()->clip_rect());
  EXPECT_FALSE(paged_apps_grid_view_->cardified_state_for_testing());
  EXPECT_EQ(0, paged_apps_grid_view_->BackgroundCardCountForTesting());
}

// This is a NonBubble test because new empty pages cannot be created with the
// ProductivityLauncher feature.
TEST_P(AppsGridViewDragNonBubbleTest,
       PeekingCardOnLastPageAfterCreatingNewPage) {
  ASSERT_TRUE(paged_apps_grid_view_);

  // Create only one page with two apps.
  model_->PopulateApps(2);
  InitiateDragForItemAtCurrentPageAt(AppsGridView::TOUCH, 0, 0,
                                     paged_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.
  InitiateDragForItemAtCurrentPageAt(AppsGridView::TOUCH, 0, 0,
                                     paged_apps_grid_view_);

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

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

TEST_P(AppsGridViewCardifiedStateTest, AppsGridIsCardifiedDuringDrag) {
  ASSERT_TRUE(paged_apps_grid_view_);

  // Create only one page with two apps.
  model_->PopulateApps(2);

  InitiateDragForItemAtCurrentPageAt(AppsGridView::TOUCH, 0, 0,
                                     paged_apps_grid_view_);

  EXPECT_TRUE(paged_apps_grid_view_->cardified_state_for_testing());

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

  EXPECT_FALSE(paged_apps_grid_view_->cardified_state_for_testing());
}

TEST_P(AppsGridViewCardifiedStateTest,
       DragWithinFolderDoesNotEnterCardifiedState) {
  ASSERT_TRUE(paged_apps_grid_view_);

  // Creates a folder item and open it.
  const size_t kTotalItems = kMaxItemsPerFolderPage;
  model_->CreateAndPopulateFolderWithApps(kTotalItems);
  test_api_->Update();
  test_api_->PressItemAt(0);
  AppsGridViewTestApi folder_grid_test_api(folder_apps_grid_view());

  // Drag the first folder child within the folder.
  InitiateDragForItemAtCurrentPageAt(AppsGridView::TOUCH, 0, 0,
                                     folder_apps_grid_view());
  const gfx::Point to =
      folder_grid_test_api.GetItemTileRectOnCurrentPageAt(0, 1).CenterPoint();
  UpdateDrag(AppsGridView::TOUCH, 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(paged_apps_grid_view_->cardified_state_for_testing());

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

TEST_P(AppsGridViewCardifiedStateTest, DragOutsideFolderEntersCardifiedState) {
  ASSERT_TRUE(paged_apps_grid_view_);

  // 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());

  // Drag the first folder child out of the folder.
  AppListItemView* drag_view = InitiateDragForItemAtCurrentPageAt(
      AppsGridView::TOUCH, 0, 0, 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::TOUCH, 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(paged_apps_grid_view_->cardified_state_for_testing());

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

TEST_P(AppsGridViewCardifiedStateTest,
       DragItemIntoFolderStaysInCardifiedState) {
  ASSERT_TRUE(paged_apps_grid_view_);

  // Create a folder item with some apps. Add another app to the main grid.
  model_->CreateAndPopulateFolderWithApps(2);
  model_->PopulateApps(1);
  InitiateDragForItemAtCurrentPageAt(AppsGridView::TOUCH, 0, 1,
                                     paged_apps_grid_view_);

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

  EXPECT_TRUE(paged_apps_grid_view_->cardified_state_for_testing());

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

TEST_P(AppsGridViewAppSortTest, ContextMenuInTopLevelAppListSortAllApps) {
  // In this test, the sort algorithm is not tested. Instead, the context menu
  // that contains the options to sort is verified to be shown in apps grid
  // view. The menu option selecting is also simulated to ensure the sorting is
  // called. The actual sort algorithm is tested in
  // chrome/browser/ui/app_list/app_list_sort_browsertest.cc.
  model_->PopulateApps(1);

  AppsGridContextMenu* context_menu = apps_grid_view_->context_menu_for_test();
  EXPECT_FALSE(context_menu->IsMenuShowing());
  EXPECT_EQ(AppListSortOrder::kCustom, model_->requested_sort_order());

  // Get a point in `apps_grid_view_` that doesn't have an item on it.
  const gfx::Point empty_space =
      apps_grid_view_->GetBoundsInScreen().CenterPoint();

  // Open the menu to test the alphabetical sort option.
  SimulateRightClickOrLongPressAt(empty_space);
  EXPECT_TRUE(context_menu->IsMenuShowing());

  // Cache the current context menu view.
  views::MenuItemView* reorder_option =
      context_menu->root_menu_item_view()->GetSubmenu()->GetMenuItemAt(1);
  ASSERT_TRUE(reorder_option->title() == u"Name");

  // Open the Reorder by Name submenu.
  const gfx::Point reorder_option_point =
      reorder_option->GetBoundsInScreen().CenterPoint();
  SimulateLeftClickOrTapAt(reorder_option_point);
  EXPECT_EQ(AppListSortOrder::kNameAlphabetical,
            model_->requested_sort_order());
  EXPECT_FALSE(context_menu->IsMenuShowing());

  // Open the menu again to test the color sort option.
  SimulateRightClickOrLongPressAt(empty_space);
  EXPECT_TRUE(context_menu->IsMenuShowing());

  reorder_option =
      context_menu->root_menu_item_view()->GetSubmenu()->GetMenuItemAt(2);
  ASSERT_TRUE(reorder_option->title() == u"Color");

  const gfx::Point color_option =
      reorder_option->GetBoundsInScreen().CenterPoint();

  SimulateLeftClickOrTapAt(color_option);
  EXPECT_EQ(AppListSortOrder::kColor, model_->requested_sort_order());
  EXPECT_FALSE(context_menu->IsMenuShowing());
}

TEST_P(AppsGridViewAppSortTest, ContextMenuOnFolderItemSortAllApps) {
  // In this test, the sort algorithm is not tested. Instead, the context menu
  // that contains the options to sort is verified to be shown on folder app
  // list item view. The menu option selecting is also simulated to ensure the
  // sorting is called. The actual sort algorithm is tested in
  // chrome/browser/ui/app_list/app_list_sort_browsertest.cc.

  // Create a folder item and update the layout.
  model_->CreateAndPopulateFolderWithApps(2);
  UpdateLayout();
  EXPECT_EQ(AppListSortOrder::kCustom, model_->requested_sort_order());

  // Get a point on the folder item.
  AppListItemView* folder_item = apps_grid_view_->view_model()->view_at(0);
  ASSERT_TRUE(folder_item->is_folder());
  gfx::Point folder_item_point = folder_item->GetBoundsInScreen().CenterPoint();

  AppsGridContextMenu* context_menu = folder_item->context_menu_for_folder();
  ASSERT_TRUE(context_menu);
  EXPECT_FALSE(context_menu->IsMenuShowing());

  // Open the menu to test the alphabetical sort option.
  SimulateRightClickOrLongPressAt(folder_item_point);
  EXPECT_TRUE(context_menu->IsMenuShowing());

  // Cache the current context menu view.
  views::MenuItemView* reorder_option =
      context_menu->root_menu_item_view()->GetSubmenu()->GetMenuItemAt(1);
  ASSERT_TRUE(reorder_option->title() == u"Name");

  // Open the Reorder by Name submenu.
  gfx::Point reorder_option_point =
      reorder_option->GetBoundsInScreen().CenterPoint();
  SimulateLeftClickOrTapAt(reorder_option_point);
  EXPECT_EQ(AppListSortOrder::kNameAlphabetical,
            model_->requested_sort_order());
  EXPECT_FALSE(context_menu->IsMenuShowing());

  // Open the menu again to test the color sort option.
  SimulateRightClickOrLongPressAt(folder_item_point);
  EXPECT_TRUE(context_menu->IsMenuShowing());

  reorder_option =
      context_menu->root_menu_item_view()->GetSubmenu()->GetMenuItemAt(2);
  ASSERT_TRUE(reorder_option->title() == u"Color");

  const gfx::Point color_option =
      reorder_option->GetBoundsInScreen().CenterPoint();

  SimulateLeftClickOrTapAt(color_option);
  EXPECT_EQ(AppListSortOrder::kColor, model_->requested_sort_order());
  EXPECT_FALSE(context_menu->IsMenuShowing());
}

}  // namespace test
}  // namespace ash
