blob: 372b8d1666aad0ea36582540375c329a1bb17995 [file] [log] [blame]
// Copyright 2013 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 "ui/app_list/presenter/app_list_presenter_impl.h"
#include <memory>
#include "base/memory/ptr_util.h"
#include "ui/app_list/presenter/app_list_presenter_delegate_factory.h"
#include "ui/app_list/presenter/test/app_list_presenter_impl_test_api.h"
#include "ui/app_list/test/app_list_test_view_delegate.h"
#include "ui/app_list/views/app_list_view.h"
#include "ui/aura/client/focus_client.h"
#include "ui/aura/test/aura_test_base.h"
#include "ui/aura/test/test_screen.h"
#include "ui/aura/window.h"
#include "ui/views/test/test_views_delegate.h"
#include "ui/wm/core/default_activation_client.h"
#include "ui/wm/core/window_util.h"
namespace app_list {
namespace {
// Test stub for AppListPresenterDelegate
class AppListPresenterDelegateTest : public AppListPresenterDelegate {
public:
AppListPresenterDelegateTest(aura::Window* container,
test::AppListTestViewDelegate* view_delegate)
: container_(container), view_delegate_(view_delegate) {}
~AppListPresenterDelegateTest() override {}
bool init_called() const { return init_called_; }
bool on_shown_called() const { return on_shown_called_; }
bool on_dismissed_called() const { return on_dismissed_called_; }
bool update_bounds_called() const { return update_bounds_called_; }
private:
// AppListPresenterDelegate:
AppListViewDelegate* GetViewDelegate() override { return view_delegate_; }
void Init(AppListView* view,
int64_t display_id,
int current_apps_page) override {
init_called_ = true;
view_ = view;
view->InitAsBubble(container_, current_apps_page);
}
void OnShown(int64_t display_id) override { on_shown_called_ = true; }
void OnDismissed() override { on_dismissed_called_ = true; }
void UpdateBounds() override { update_bounds_called_ = true; }
gfx::Vector2d GetVisibilityAnimationOffset(aura::Window*) override {
return gfx::Vector2d(0, 0);
}
private:
aura::Window* container_;
test::AppListTestViewDelegate* view_delegate_;
AppListView* view_ = nullptr;
bool init_called_ = false;
bool on_shown_called_ = false;
bool on_dismissed_called_ = false;
bool update_bounds_called_ = false;
views::TestViewsDelegate views_delegate_;
DISALLOW_COPY_AND_ASSIGN(AppListPresenterDelegateTest);
};
// Test fake for AppListPresenterDelegateFactory, creates instances of
// AppListPresenterDelegateTest.
class AppListPresenterDelegateFactoryTest
: public AppListPresenterDelegateFactory {
public:
explicit AppListPresenterDelegateFactoryTest(aura::Window* container)
: container_(container) {}
~AppListPresenterDelegateFactoryTest() override {}
// AppListPresenterDelegateFactory:
std::unique_ptr<AppListPresenterDelegate> GetDelegate(
AppListPresenterImpl* presenter) override {
return base::MakeUnique<AppListPresenterDelegateTest>(
container_, &app_list_view_delegate_);
}
private:
aura::Window* container_;
test::AppListTestViewDelegate app_list_view_delegate_;
DISALLOW_COPY_AND_ASSIGN(AppListPresenterDelegateFactoryTest);
};
} // namespace
class AppListPresenterImplTest : public aura::test::AuraTestBase {
public:
AppListPresenterImplTest();
~AppListPresenterImplTest() override;
AppListPresenterImpl* presenter() { return presenter_.get(); }
aura::Window* container() { return container_.get(); }
int64_t GetDisplayId() { return test_screen()->GetPrimaryDisplay().id(); }
// Don't cache the return of this method - a new delegate is created every
// time the app list is shown.
AppListPresenterDelegateTest* delegate() {
return static_cast<AppListPresenterDelegateTest*>(
presenter_test_api_->presenter_delegate());
}
// aura::test::AuraTestBase:
void SetUp() override;
void TearDown() override;
private:
std::unique_ptr<AppListPresenterImpl> presenter_;
std::unique_ptr<aura::Window> container_;
std::unique_ptr<test::AppListPresenterImplTestApi> presenter_test_api_;
DISALLOW_COPY_AND_ASSIGN(AppListPresenterImplTest);
};
AppListPresenterImplTest::AppListPresenterImplTest() {}
AppListPresenterImplTest::~AppListPresenterImplTest() {}
void AppListPresenterImplTest::SetUp() {
AuraTestBase::SetUp();
new wm::DefaultActivationClient(root_window());
container_.reset(CreateNormalWindow(0, root_window(), nullptr));
presenter_ = base::MakeUnique<AppListPresenterImpl>(
base::MakeUnique<AppListPresenterDelegateFactoryTest>(container_.get()));
presenter_test_api_ =
base::MakeUnique<test::AppListPresenterImplTestApi>(presenter());
}
void AppListPresenterImplTest::TearDown() {
container_.reset();
AuraTestBase::TearDown();
}
// Tests that app launcher is dismissed when focus moves to a window which is
// not app list window's sibling and that appropriate delegate callbacks are
// executed when the app launcher is shown and then when the app launcher is
// dismissed.
TEST_F(AppListPresenterImplTest, HideOnFocusOut) {
aura::client::FocusClient* focus_client =
aura::client::GetFocusClient(root_window());
presenter()->Show(GetDisplayId());
EXPECT_TRUE(delegate()->init_called());
EXPECT_TRUE(delegate()->on_shown_called());
EXPECT_FALSE(delegate()->on_dismissed_called());
EXPECT_FALSE(delegate()->update_bounds_called());
focus_client->FocusWindow(presenter()->GetWindow());
EXPECT_TRUE(presenter()->GetTargetVisibility());
std::unique_ptr<aura::Window> window(
CreateNormalWindow(1, root_window(), nullptr));
focus_client->FocusWindow(window.get());
EXPECT_TRUE(delegate()->on_dismissed_called());
EXPECT_FALSE(delegate()->update_bounds_called());
EXPECT_FALSE(presenter()->GetTargetVisibility());
}
// Tests that app launcher remains visible when focus moves to a window which
// is app list window's sibling and that appropriate delegate callbacks are
// executed when the app launcher is shown.
TEST_F(AppListPresenterImplTest, RemainVisibleWhenFocusingToSibling) {
aura::client::FocusClient* focus_client =
aura::client::GetFocusClient(root_window());
presenter()->Show(GetDisplayId());
focus_client->FocusWindow(presenter()->GetWindow());
EXPECT_TRUE(presenter()->GetTargetVisibility());
EXPECT_TRUE(delegate()->init_called());
EXPECT_TRUE(delegate()->on_shown_called());
EXPECT_FALSE(delegate()->on_dismissed_called());
EXPECT_FALSE(delegate()->update_bounds_called());
// Create a sibling window.
std::unique_ptr<aura::Window> window(
CreateNormalWindow(1, container(), nullptr));
focus_client->FocusWindow(window.get());
EXPECT_TRUE(presenter()->GetTargetVisibility());
EXPECT_FALSE(delegate()->on_dismissed_called());
EXPECT_FALSE(delegate()->update_bounds_called());
}
// Tests that UpdateBounds is called on the delegate when the root window
// is resized.
TEST_F(AppListPresenterImplTest, RootWindowResize) {
presenter()->Show(GetDisplayId());
EXPECT_FALSE(delegate()->update_bounds_called());
gfx::Rect bounds = root_window()->bounds();
bounds.Inset(-10, 0);
root_window()->SetBounds(bounds);
EXPECT_TRUE(delegate()->update_bounds_called());
}
// Tests that the app list is dismissed and the delegate is destroyed when the
// app list's widget is destroyed.
TEST_F(AppListPresenterImplTest, WidgetDestroyed) {
presenter()->Show(GetDisplayId());
EXPECT_TRUE(presenter()->GetTargetVisibility());
presenter()->GetView()->GetWidget()->CloseNow();
EXPECT_FALSE(presenter()->GetTargetVisibility());
EXPECT_FALSE(delegate());
}
} // namespace app_list