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 "athena/home/athena_start_page_view.h" 6 7#include "athena/home/home_card_constants.h" 8#include "athena/test/athena_test_base.h" 9#include "base/format_macros.h" 10#include "base/strings/stringprintf.h" 11#include "base/strings/utf_string_conversions.h" 12#include "ui/app_list/app_list_switches.h" 13#include "ui/app_list/search_box_model.h" 14#include "ui/app_list/test/app_list_test_model.h" 15#include "ui/app_list/test/app_list_test_view_delegate.h" 16#include "ui/app_list/views/search_box_view.h" 17#include "ui/gfx/geometry/rect.h" 18#include "ui/views/controls/textfield/textfield.h" 19 20namespace athena { 21 22namespace { 23 24// The number of dummy applications in this tetst. 25const size_t kNumApps = 10; 26 27} 28 29class AthenaTestViewDelegate : public app_list::test::AppListTestViewDelegate { 30 public: 31 AthenaTestViewDelegate() {} 32 virtual ~AthenaTestViewDelegate() {} 33 34 private: 35 // app_list::AppListViewDelegate: 36 virtual views::View* CreateStartPageWebView(const gfx::Size& size) OVERRIDE { 37 return new views::View(); 38 } 39 40 DISALLOW_COPY_AND_ASSIGN(AthenaTestViewDelegate); 41}; 42 43class AthenaStartPageViewTest : public test::AthenaTestBase { 44 public: 45 AthenaStartPageViewTest() {} 46 virtual ~AthenaStartPageViewTest() {} 47 48 // testing::Test: 49 virtual void SetUp() OVERRIDE { 50 test::AthenaTestBase::SetUp(); 51 app_list::test::AppListTestModel* model = view_delegate_.GetTestModel(); 52 for (size_t i = 0; i < kNumApps; ++i) { 53 model->AddItem(new app_list::test::AppListTestModel::AppListTestItem( 54 base::StringPrintf("id-%" PRIuS, i), model)); 55 } 56 57 view_.reset(new AthenaStartPageView(&view_delegate_)); 58 SetSize(gfx::Size(1280, 800)); 59 } 60 virtual void TearDown() OVERRIDE { 61 view_.reset(); 62 test::AthenaTestBase::TearDown(); 63 } 64 65 protected: 66 void SetSize(const gfx::Size& new_size) { 67 view_->SetSize(new_size); 68 view_->Layout(); 69 } 70 71 gfx::Rect GetIconsBounds() const { 72 return view_->app_icon_container_->layer()->GetTargetBounds(); 73 } 74 75 gfx::Rect GetControlBounds() const { 76 return view_->control_icon_container_->layer()->GetTargetBounds(); 77 } 78 79 gfx::Rect GetSearchBoxBounds() const { 80 return view_->search_box_container_->layer()->GetTargetBounds(); 81 } 82 83 gfx::Rect GetLogoBounds() const { 84 return view_->logo_->layer()->GetTargetBounds(); 85 } 86 87 bool IsLogoVisible() const { 88 return view_->logo_->layer()->GetTargetOpacity() > 0 && 89 view_->logo_->layer()->GetTargetVisibility(); 90 } 91 92 gfx::Size GetSearchBoxPreferredSize() { 93 return view_->search_box_container_->GetPreferredSize(); 94 } 95 96 void SetSearchQuery(const base::string16& query) { 97 view_delegate_.GetModel()->search_box()->SetText(query); 98 } 99 100 base::string16 GetVisibleQuery() { 101 return view_->search_box_view_->search_box()->text(); 102 } 103 104 scoped_ptr<AthenaStartPageView> view_; 105 106 private: 107 AthenaTestViewDelegate view_delegate_; 108 109 DISALLOW_COPY_AND_ASSIGN(AthenaStartPageViewTest); 110}; 111 112TEST_F(AthenaStartPageViewTest, BasicLayout) { 113 // BOTTOM state. logo is invisible. icons, search box, and controls are 114 // arranged horizontally. 115 EXPECT_FALSE(IsLogoVisible()); 116 117 // Three components are aligned at the middle point. 118 EXPECT_NEAR(GetIconsBounds().CenterPoint().y(), 119 GetControlBounds().CenterPoint().y(), 120 1); 121 EXPECT_NEAR(GetIconsBounds().CenterPoint().y(), 122 GetSearchBoxBounds().CenterPoint().y(), 123 1); 124 EXPECT_NEAR(GetControlBounds().CenterPoint().y(), 125 GetSearchBoxBounds().CenterPoint().y(), 126 1); 127 128 // Horizonttaly aligned in the order of icons, search_box, and controls. 129 EXPECT_LE(GetIconsBounds().right(), GetSearchBoxBounds().x()); 130 EXPECT_LE(GetSearchBoxBounds().right(), GetControlBounds().x()); 131 EXPECT_LE(0, GetIconsBounds().y()); 132 133 // Search box should appear in the middle. 134 EXPECT_NEAR(GetSearchBoxBounds().CenterPoint().x(), 135 view_->bounds().CenterPoint().x(), 136 1); 137 138 // Should fit inside of the home card height. 139 EXPECT_GE(kHomeCardHeight, GetIconsBounds().height()); 140 EXPECT_GE(kHomeCardHeight, GetSearchBoxBounds().height()); 141 EXPECT_GE(kHomeCardHeight, GetControlBounds().height()); 142 EXPECT_EQ(GetSearchBoxPreferredSize().ToString(), 143 GetSearchBoxBounds().size().ToString()); 144 145 // CENTERED state. logo is visible. search box appears below the logo, 146 // icons and controls are arranged horizontally and below the search box. 147 view_->SetLayoutState(1.0f); 148 EXPECT_TRUE(IsLogoVisible()); 149 EXPECT_NEAR(GetLogoBounds().x() + GetLogoBounds().width() / 2, 150 GetSearchBoxBounds().x() + GetSearchBoxBounds().width() / 2, 151 1); 152 EXPECT_LE(GetLogoBounds().bottom(), GetSearchBoxBounds().y()); 153 EXPECT_EQ(GetIconsBounds().y(), GetControlBounds().y()); 154 EXPECT_LE(GetIconsBounds().right(), GetControlBounds().x()); 155 EXPECT_LE(GetSearchBoxBounds().bottom(), GetIconsBounds().y()); 156} 157 158TEST_F(AthenaStartPageViewTest, NarrowLayout) { 159 SetSize(gfx::Size(800, 1280)); 160 161 // BOTTOM state. Similar to BasicLayout. 162 EXPECT_FALSE(IsLogoVisible()); 163 // Three components are aligned at the middle point. 164 EXPECT_NEAR(GetIconsBounds().CenterPoint().y(), 165 GetControlBounds().CenterPoint().y(), 166 1); 167 EXPECT_NEAR(GetIconsBounds().CenterPoint().y(), 168 GetSearchBoxBounds().CenterPoint().y(), 169 1); 170 EXPECT_NEAR(GetControlBounds().CenterPoint().y(), 171 GetSearchBoxBounds().CenterPoint().y(), 172 1); 173 174 // Horizonttaly aligned in the order of icons, search_box, and controls. 175 EXPECT_LE(GetIconsBounds().right(), GetSearchBoxBounds().x()); 176 EXPECT_LE(GetSearchBoxBounds().right(), GetControlBounds().x()); 177 EXPECT_LE(0, GetIconsBounds().y()); 178 179 // Search box should appear in the middle. 180 EXPECT_NEAR(GetSearchBoxBounds().CenterPoint().x(), 181 view_->bounds().CenterPoint().x(), 182 1); 183 184 // Should fit inside of the home card height. 185 EXPECT_GE(kHomeCardHeight, GetIconsBounds().height()); 186 EXPECT_GE(kHomeCardHeight, GetSearchBoxBounds().height()); 187 EXPECT_GE(kHomeCardHeight, GetControlBounds().height()); 188 189 // Search box is narrower because of the size is too narrow. 190 EXPECT_GT(GetSearchBoxPreferredSize().width(), GetSearchBoxBounds().width()); 191 EXPECT_EQ(GetSearchBoxPreferredSize().height(), 192 GetSearchBoxBounds().height()); 193 194 // CENTERED state. Search box should be back to the preferred size. 195 view_->SetLayoutState(1.0f); 196 EXPECT_EQ(GetSearchBoxPreferredSize().ToString(), 197 GetSearchBoxBounds().size().ToString()); 198 199 // Back to BOTTOM state, the search box shrinks again. 200 view_->SetLayoutState(0.0f); 201 EXPECT_GT(GetSearchBoxPreferredSize().width(), GetSearchBoxBounds().width()); 202 203 // Then set back to the original size, now the size is wide enough so the 204 // search box bounds becomes as preferred. 205 SetSize(gfx::Size(1280, 800)); 206 EXPECT_EQ(GetSearchBoxPreferredSize().ToString(), 207 GetSearchBoxBounds().size().ToString()); 208} 209 210TEST_F(AthenaStartPageViewTest, SearchBox) { 211 view_->SetLayoutState(1.0f); 212 EXPECT_TRUE(IsLogoVisible()); 213 214 const gfx::Rect base_search_box_bounds = GetSearchBoxBounds(); 215 216 const base::string16 query = base::UTF8ToUTF16("test"); 217 SetSearchQuery(query); 218 219 EXPECT_FALSE(IsLogoVisible()); 220 EXPECT_GT(base_search_box_bounds.y(), GetSearchBoxBounds().y()); 221 EXPECT_EQ(query, GetVisibleQuery()); 222 223 SetSearchQuery(base::string16()); 224 EXPECT_TRUE(IsLogoVisible()); 225 EXPECT_EQ(base_search_box_bounds.ToString(), GetSearchBoxBounds().ToString()); 226 EXPECT_TRUE(GetVisibleQuery().empty()); 227} 228 229} // namespace athena 230