1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/ui/app_list/app_list_shower_views.h"
6
7#include "base/files/file_path.h"
8#include "chrome/browser/apps/scoped_keep_alive.h"
9#include "chrome/browser/profiles/profile.h"
10#include "chrome/browser/ui/app_list/app_list_shower_delegate.h"
11#include "chrome/browser/ui/app_list/test/fake_profile.h"
12#include "testing/gtest/include/gtest/gtest.h"
13
14namespace {
15
16class FakeAppListShower : public AppListShower {
17 public:
18  explicit FakeAppListShower(AppListShowerDelegate* delegate)
19      : AppListShower(delegate), has_view_(false), visible_(false) {}
20
21  // AppListShower:
22  virtual void HandleViewBeingDestroyed() OVERRIDE {
23    AppListShower::HandleViewBeingDestroyed();
24    has_view_ = false;
25    visible_ = false;
26  }
27
28  virtual bool IsAppListVisible() const OVERRIDE { return visible_; }
29
30  virtual app_list::AppListView* MakeViewForCurrentProfile() OVERRIDE {
31    has_view_ = true;
32    return NULL;
33  }
34
35  virtual void UpdateViewForNewProfile() OVERRIDE {}
36
37  virtual void Show() OVERRIDE {
38    visible_ = true;
39  }
40
41  virtual void Hide() OVERRIDE {
42    visible_ = false;
43  }
44
45  virtual bool HasView() const OVERRIDE {
46    return has_view_;
47  }
48
49 private:
50  bool has_view_;
51  bool visible_;
52
53  DISALLOW_COPY_AND_ASSIGN(FakeAppListShower);
54};
55
56}  // namespace
57
58class AppListShowerUnitTest : public testing::Test,
59                              public AppListShowerDelegate {
60 public:
61  AppListShowerUnitTest()
62      : views_created_(0),
63        views_dismissed_(0) {}
64
65  virtual void SetUp() OVERRIDE {
66    shower_.reset(new FakeAppListShower(this));
67    profile1_ = CreateProfile("p1").Pass();
68    profile2_ = CreateProfile("p2").Pass();
69  }
70
71  virtual void TearDown() OVERRIDE {
72  }
73
74  scoped_ptr<FakeProfile> CreateProfile(const std::string& name) {
75    return make_scoped_ptr(new FakeProfile(name));
76  }
77
78  // AppListShowerDelegate:
79  virtual AppListViewDelegate* GetViewDelegateForCreate() OVERRIDE {
80    return NULL;
81  }
82
83  bool HasKeepAlive() const {
84    return shower_->keep_alive_.get() != NULL;
85  }
86
87  virtual void OnViewCreated() OVERRIDE { ++views_created_; }
88  virtual void OnViewDismissed() OVERRIDE { ++views_dismissed_; }
89  virtual void MoveNearCursor(app_list::AppListView* view) OVERRIDE {}
90
91 protected:
92  scoped_ptr<FakeAppListShower> shower_;
93  scoped_ptr<FakeProfile> profile1_;
94  scoped_ptr<FakeProfile> profile2_;
95
96  int views_created_;
97  int views_dismissed_;
98};
99
100TEST_F(AppListShowerUnitTest, Preconditions) {
101  EXPECT_FALSE(shower_->IsAppListVisible());
102  EXPECT_FALSE(shower_->HasView());
103  EXPECT_FALSE(HasKeepAlive());
104}
105
106TEST_F(AppListShowerUnitTest, ShowForProfilePutsViewOnScreen) {
107  shower_->ShowForProfile(profile1_.get());
108  EXPECT_TRUE(shower_->IsAppListVisible());
109  EXPECT_TRUE(shower_->HasView());
110  EXPECT_TRUE(HasKeepAlive());
111}
112
113TEST_F(AppListShowerUnitTest, HidingViewRemovesKeepalive) {
114  shower_->ShowForProfile(profile1_.get());
115  shower_->DismissAppList();
116  EXPECT_FALSE(shower_->IsAppListVisible());
117  EXPECT_TRUE(shower_->HasView());
118  EXPECT_FALSE(HasKeepAlive());
119}
120
121TEST_F(AppListShowerUnitTest, HideAndShowReusesView) {
122  EXPECT_EQ(0, views_created_);
123  shower_->ShowForProfile(profile1_.get());
124  EXPECT_EQ(1, views_created_);
125  EXPECT_EQ(0, views_dismissed_);
126  shower_->DismissAppList();
127  EXPECT_EQ(1, views_dismissed_);
128  shower_->ShowForProfile(profile1_.get());
129  EXPECT_EQ(1, views_created_);
130}
131
132TEST_F(AppListShowerUnitTest, CloseAndShowRecreatesView) {
133  shower_->ShowForProfile(profile1_.get());
134  shower_->HandleViewBeingDestroyed();
135  // Destroying implies hiding. A separate notification shouldn't go out.
136  EXPECT_EQ(0, views_dismissed_);
137  shower_->ShowForProfile(profile1_.get());
138  EXPECT_EQ(2, views_created_);
139}
140
141TEST_F(AppListShowerUnitTest, CloseRemovesView) {
142  shower_->ShowForProfile(profile1_.get());
143  shower_->HandleViewBeingDestroyed();
144  EXPECT_FALSE(shower_->IsAppListVisible());
145  EXPECT_FALSE(shower_->HasView());
146  EXPECT_FALSE(HasKeepAlive());
147}
148
149TEST_F(AppListShowerUnitTest, CloseAppListClearsProfile) {
150  EXPECT_EQ(NULL, shower_->profile());
151  shower_->ShowForProfile(profile1_.get());
152  EXPECT_EQ(profile1_.get(), shower_->profile());
153  shower_->HandleViewBeingDestroyed();
154  EXPECT_EQ(NULL, shower_->profile());
155}
156
157TEST_F(AppListShowerUnitTest, SwitchingProfiles) {
158  shower_->ShowForProfile(profile1_.get());
159  EXPECT_EQ("p1", shower_->profile()->GetProfileName());
160  shower_->ShowForProfile(profile2_.get());
161  EXPECT_EQ("p2", shower_->profile()->GetProfileName());
162
163  // Shouldn't create new view for second profile - it should switch in place.
164  EXPECT_EQ(1, views_created_);
165  EXPECT_EQ(0, views_dismissed_);
166}
167