- add sources.
[platform/framework/web/crosswalk.git] / src / ui / app_list / app_list_model_unittest.cc
1 // Copyright 2013 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 "ui/app_list/app_list_model.h"
6
7 #include <map>
8
9 #include "base/strings/utf_string_conversions.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11 #include "ui/app_list/app_list_folder_item.h"
12 #include "ui/app_list/app_list_item_model.h"
13 #include "ui/app_list/app_list_model_observer.h"
14 #include "ui/app_list/test/app_list_test_model.h"
15 #include "ui/base/models/list_model_observer.h"
16
17 namespace app_list {
18
19 namespace {
20
21 class TestObserver : public AppListModelObserver,
22                      public AppListItemListObserver {
23  public:
24   TestObserver()
25       : status_changed_count_(0),
26         users_changed_count_(0),
27         signin_changed_count_(0),
28         items_added_(0),
29         items_removed_(0),
30         items_moved_(0) {
31   }
32   virtual ~TestObserver() {
33   }
34
35   // AppListModelObserver
36   virtual void OnAppListModelStatusChanged() OVERRIDE {
37     ++status_changed_count_;
38   }
39
40   virtual void OnAppListModelUsersChanged() OVERRIDE {
41     ++users_changed_count_;
42   }
43
44   virtual void OnAppListModelSigninStatusChanged() OVERRIDE {
45     ++signin_changed_count_;
46   }
47
48   // AppListItemListObserver
49   virtual void OnListItemAdded(size_t index, AppListItemModel* item) OVERRIDE {
50     items_added_++;
51   }
52
53   virtual void OnListItemRemoved(size_t index,
54                                  AppListItemModel* item) OVERRIDE {
55     items_removed_++;
56   }
57
58   virtual void OnListItemMoved(size_t from_index,
59                                size_t to_index,
60                                AppListItemModel* item) OVERRIDE {
61     items_moved_++;
62   }
63
64   int status_changed_count() const { return status_changed_count_; }
65   int users_changed_count() const { return users_changed_count_; }
66   int signin_changed_count() const { return signin_changed_count_; }
67   size_t items_added() { return items_added_; }
68   size_t items_removed() { return items_removed_; }
69   size_t items_moved() { return items_moved_; }
70
71   void ResetCounts() {
72     status_changed_count_ = 0;
73     users_changed_count_ = 0;
74     signin_changed_count_ = 0;
75     items_added_ = 0;
76     items_removed_ = 0;
77     items_moved_ = 0;
78   }
79
80  private:
81   int status_changed_count_;
82   int users_changed_count_;
83   int signin_changed_count_;
84   size_t items_added_;
85   size_t items_removed_;
86   size_t items_moved_;
87
88   DISALLOW_COPY_AND_ASSIGN(TestObserver);
89 };
90
91 }  // namespace
92
93 class AppListModelTest : public testing::Test {
94  public:
95   AppListModelTest() {}
96   virtual ~AppListModelTest() {}
97
98   // testing::Test overrides:
99   virtual void SetUp() OVERRIDE {
100     model_.AddObserver(&observer_);
101     model_.item_list()->AddObserver(&observer_);
102   }
103   virtual void TearDown() OVERRIDE {
104     model_.RemoveObserver(&observer_);
105     model_.item_list()->RemoveObserver(&observer_);
106   }
107
108  protected:
109   bool ItemObservedByFolder(AppListFolderItem* folder,
110                             AppListItemModel* item) {
111     return item->observers_.HasObserver(folder);
112   }
113
114   test::AppListTestModel model_;
115   TestObserver observer_;
116
117  private:
118   DISALLOW_COPY_AND_ASSIGN(AppListModelTest);
119 };
120
121 TEST_F(AppListModelTest, SetStatus) {
122   EXPECT_EQ(AppListModel::STATUS_NORMAL, model_.status());
123   model_.SetStatus(AppListModel::STATUS_SYNCING);
124   EXPECT_EQ(1, observer_.status_changed_count());
125   EXPECT_EQ(AppListModel::STATUS_SYNCING, model_.status());
126   model_.SetStatus(AppListModel::STATUS_NORMAL);
127   EXPECT_EQ(2, observer_.status_changed_count());
128   // Set the same status, no change is expected.
129   model_.SetStatus(AppListModel::STATUS_NORMAL);
130   EXPECT_EQ(2, observer_.status_changed_count());
131 }
132
133 TEST_F(AppListModelTest, SetUsers) {
134   EXPECT_EQ(0u, model_.users().size());
135   AppListModel::Users users;
136   users.push_back(AppListModel::User());
137   users[0].name = UTF8ToUTF16("test");
138   model_.SetUsers(users);
139   EXPECT_EQ(1, observer_.users_changed_count());
140   ASSERT_EQ(1u, model_.users().size());
141   EXPECT_EQ(UTF8ToUTF16("test"), model_.users()[0].name);
142 }
143
144 TEST_F(AppListModelTest, SetSignedIn) {
145   EXPECT_TRUE(model_.signed_in());
146   model_.SetSignedIn(false);
147   EXPECT_EQ(1, observer_.signin_changed_count());
148   EXPECT_FALSE(model_.signed_in());
149   model_.SetSignedIn(true);
150   EXPECT_EQ(2, observer_.signin_changed_count());
151   EXPECT_TRUE(model_.signed_in());
152   // Set the same signin state, no change is expected.
153   model_.SetSignedIn(true);
154   EXPECT_EQ(2, observer_.signin_changed_count());
155 }
156
157 TEST_F(AppListModelTest, AppsObserver) {
158   const size_t num_apps = 2;
159   model_.PopulateApps(num_apps);
160   EXPECT_EQ(num_apps, observer_.items_added());
161 }
162
163 TEST_F(AppListModelTest, ModelGetItem) {
164   const size_t num_apps = 2;
165   model_.PopulateApps(num_apps);
166   AppListItemModel* item0 = model_.item_list()->item_at(0);
167   ASSERT_TRUE(item0);
168   EXPECT_EQ(model_.GetItemName(0), item0->id());
169   AppListItemModel* item1 = model_.item_list()->item_at(1);
170   ASSERT_TRUE(item1);
171   EXPECT_EQ(model_.GetItemName(1), item1->id());
172 }
173
174 TEST_F(AppListModelTest, ModelFindItem) {
175   const size_t num_apps = 2;
176   model_.PopulateApps(num_apps);
177   std::string item_name0 = model_.GetItemName(0);
178   AppListItemModel* item0 = model_.item_list()->FindItem(item_name0);
179   ASSERT_TRUE(item0);
180   EXPECT_EQ(item_name0, item0->id());
181   std::string item_name1 = model_.GetItemName(1);
182   AppListItemModel* item1 = model_.item_list()->FindItem(item_name1);
183   ASSERT_TRUE(item1);
184   EXPECT_EQ(item_name1, item1->id());
185 }
186
187 TEST_F(AppListModelTest, ModelAddItem) {
188   const size_t num_apps = 2;
189   model_.PopulateApps(num_apps);
190   // Adding another item will add it to the end.
191   model_.CreateAndAddItem("Added Item 1");
192   ASSERT_EQ(num_apps + 1, model_.item_list()->item_count());
193   EXPECT_EQ("Added Item 1", model_.item_list()->item_at(num_apps)->id());
194   // Add an item between items 0 and 1.
195   app_list::AppListItemModel* item0 = model_.item_list()->item_at(0);
196   ASSERT_TRUE(item0);
197   app_list::AppListItemModel* item1 = model_.item_list()->item_at(1);
198   ASSERT_TRUE(item1);
199   app_list::AppListItemModel* item2 =
200       model_.CreateItem("Added Item 2", "Added Item 2");
201   item2->set_position(item0->position().CreateBetween(item1->position()));
202   model_.item_list()->AddItem(item2);
203   EXPECT_EQ(num_apps + 2, model_.item_list()->item_count());
204   EXPECT_EQ("Added Item 2", model_.item_list()->item_at(1)->id());
205 }
206
207 TEST_F(AppListModelTest, ModelMoveItem) {
208   const size_t num_apps = 3;
209   model_.PopulateApps(num_apps);
210   // Adding another item will add it to the end.
211   model_.CreateAndAddItem("Inserted Item");
212   ASSERT_EQ(num_apps + 1, model_.item_list()->item_count());
213   // Move it to the position 1.
214   model_.item_list()->MoveItem(num_apps, 1);
215   AppListItemModel* item = model_.item_list()->item_at(1);
216   ASSERT_TRUE(item);
217   EXPECT_EQ("Inserted Item", item->id());
218 }
219
220 TEST_F(AppListModelTest, ModelRemoveItem) {
221   const size_t num_apps = 4;
222   model_.PopulateApps(num_apps);
223   // Remove an item in the middle.
224   model_.item_list()->DeleteItem(model_.GetItemName(1));
225   EXPECT_EQ(num_apps - 1, model_.item_list()->item_count());
226   EXPECT_EQ(1u, observer_.items_removed());
227   // Remove the first item in the list.
228   model_.item_list()->DeleteItem(model_.GetItemName(0));
229   EXPECT_EQ(num_apps - 2, model_.item_list()->item_count());
230   EXPECT_EQ(2u, observer_.items_removed());
231   // Remove the last item in the list.
232   model_.item_list()->DeleteItem(model_.GetItemName(num_apps - 1));
233   EXPECT_EQ(num_apps - 3, model_.item_list()->item_count());
234   EXPECT_EQ(3u, observer_.items_removed());
235   // Ensure that the first item is the expected one
236   AppListItemModel* item0 = model_.item_list()->item_at(0);
237   ASSERT_TRUE(item0);
238   EXPECT_EQ(model_.GetItemName(2), item0->id());
239 }
240
241 TEST_F(AppListModelTest, ModelRemoveItemByType) {
242   const size_t num_apps = 4;
243   model_.PopulateApps(num_apps);
244   model_.item_list()->AddItem(new AppListFolderItem("folder1"));
245   model_.item_list()->AddItem(new AppListFolderItem("folder2"));
246   model_.item_list()->DeleteItemsByType(test::AppListTestModel::kAppType);
247   EXPECT_EQ(num_apps, observer_.items_removed());
248   EXPECT_EQ(2u, model_.item_list()->item_count());
249   model_.item_list()->DeleteItemsByType(AppListFolderItem::kAppType);
250   EXPECT_EQ(num_apps + 2, observer_.items_removed());
251   EXPECT_EQ(0u, model_.item_list()->item_count());
252   // Delete all items
253   observer_.ResetCounts();
254   model_.PopulateApps(num_apps);
255   model_.item_list()->AddItem(new AppListFolderItem("folder1"));
256   model_.item_list()->AddItem(new AppListFolderItem("folder2"));
257   model_.item_list()->DeleteItemsByType(NULL /* all items */);
258   EXPECT_EQ(num_apps + 2, observer_.items_removed());
259   EXPECT_EQ(0u, model_.item_list()->item_count());
260 }
261
262 TEST_F(AppListModelTest, AppOrder) {
263   const size_t num_apps = 5;
264   model_.PopulateApps(num_apps);
265   // Ensure order is preserved.
266   for (size_t i = 1; i < num_apps; ++i) {
267     EXPECT_TRUE(model_.item_list()->item_at(i)->position().GreaterThan(
268         model_.item_list()->item_at(i - 1)->position()));
269   }
270   // Move an app
271   model_.item_list()->MoveItem(num_apps - 1, 1);
272   // Ensure order is preserved.
273   for (size_t i = 1; i < num_apps; ++i) {
274     EXPECT_TRUE(model_.item_list()->item_at(i)->position().GreaterThan(
275         model_.item_list()->item_at(i - 1)->position()));
276   }
277 }
278
279 TEST_F(AppListModelTest, FolderItem) {
280   AppListFolderItem* folder = new AppListFolderItem("folder1");
281   const size_t num_folder_apps = 8;
282   const size_t num_observed_apps = 4;
283   for (int i = 0; static_cast<size_t>(i) < num_folder_apps; ++i) {
284     std::string name = model_.GetItemName(i);
285     folder->item_list()->AddItem(model_.CreateItem(name, name));
286   }
287   // Check that items 0 and 3 are observed.
288   EXPECT_TRUE(ItemObservedByFolder(folder, folder->item_list()->item_at(0)));
289   EXPECT_TRUE(ItemObservedByFolder(
290       folder, folder->item_list()->item_at(num_observed_apps - 1)));
291   // Check that item 4 is not observed.
292   EXPECT_FALSE(ItemObservedByFolder(
293       folder, folder->item_list()->item_at(num_observed_apps)));
294   folder->item_list()->MoveItem(num_observed_apps, 0);
295   // Confirm that everything was moved where expected.
296   EXPECT_EQ(model_.GetItemName(num_observed_apps),
297             folder->item_list()->item_at(0)->id());
298   EXPECT_EQ(model_.GetItemName(0),
299             folder->item_list()->item_at(1)->id());
300   EXPECT_EQ(model_.GetItemName(num_observed_apps - 1),
301             folder->item_list()->item_at(num_observed_apps)->id());
302   // Check that items 0 and 3 are observed.
303   EXPECT_TRUE(ItemObservedByFolder(folder, folder->item_list()->item_at(0)));
304   EXPECT_TRUE(ItemObservedByFolder(
305       folder, folder->item_list()->item_at(num_observed_apps - 1)));
306   // Check that item 4 is not observed.
307   EXPECT_FALSE(ItemObservedByFolder(
308       folder, folder->item_list()->item_at(num_observed_apps)));
309 }
310
311 }  // namespace app_list