- add sources.
[platform/framework/web/crosswalk.git] / src / ui / app_list / cocoa / apps_search_box_controller_unittest.mm
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 #import "ui/app_list/cocoa/apps_search_box_controller.h"
6
7 #include "base/mac/scoped_nsobject.h"
8 #include "base/strings/sys_string_conversions.h"
9 #include "base/strings/utf_string_conversions.h"
10 #import "testing/gtest_mac.h"
11 #include "ui/app_list/app_list_menu.h"
12 #include "ui/app_list/app_list_model_observer.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 #import "ui/base/cocoa/menu_controller.h"
17 #import "ui/base/test/ui_cocoa_test_helper.h"
18
19 @interface TestAppsSearchBoxDelegate : NSObject<AppsSearchBoxDelegate> {
20  @private
21   app_list::SearchBoxModel searchBoxModel_;
22   app_list::test::AppListTestViewDelegate appListDelegate_;
23   app_list::test::AppListTestModel appListModel_;
24   int textChangeCount_;
25 }
26
27 @property(assign, nonatomic) int textChangeCount;
28
29 @end
30
31 @implementation TestAppsSearchBoxDelegate
32
33 @synthesize textChangeCount = textChangeCount_;
34
35 - (id)init {
36   if ((self = [super init])) {
37     app_list::AppListModel::Users users(2);
38     users[0].name = ASCIIToUTF16("user1");
39     users[1].name = ASCIIToUTF16("user2");
40     users[1].email = ASCIIToUTF16("user2@chromium.org");
41     users[1].active = true;
42     appListModel_.SetUsers(users);
43   }
44   return self;
45 }
46
47 - (app_list::SearchBoxModel*)searchBoxModel {
48   return &searchBoxModel_;
49 }
50
51 - (app_list::AppListViewDelegate*)appListDelegate {
52   return &appListDelegate_;
53 }
54
55 - (BOOL)control:(NSControl*)control
56                textView:(NSTextView*)textView
57     doCommandBySelector:(SEL)command {
58   return NO;
59 }
60
61 - (void)modelTextDidChange {
62   ++textChangeCount_;
63 }
64
65 - (CGFloat)bubbleCornerRadius {
66   return 3;
67 }
68
69 - (app_list::AppListModel*)appListModel {
70   return &appListModel_;
71 }
72
73 @end
74
75 namespace app_list {
76 namespace test {
77
78 class AppsSearchBoxControllerTest : public ui::CocoaTest,
79                                     public AppListModelObserver {
80  public:
81   AppsSearchBoxControllerTest() {
82     Init();
83   }
84
85   virtual void SetUp() OVERRIDE {
86     apps_search_box_controller_.reset(
87         [[AppsSearchBoxController alloc] initWithFrame:
88             NSMakeRect(0, 0, 400, 100)]);
89     delegate_.reset([[TestAppsSearchBoxDelegate alloc] init]);
90     [apps_search_box_controller_ setDelegate:delegate_];
91     [delegate_ appListModel]->AddObserver(this);
92
93     ui::CocoaTest::SetUp();
94     [[test_window() contentView] addSubview:[apps_search_box_controller_ view]];
95   }
96
97   virtual void TearDown() OVERRIDE {
98     [delegate_ appListModel]->RemoveObserver(this);
99     [apps_search_box_controller_ setDelegate:nil];
100     ui::CocoaTest::TearDown();
101   }
102
103   void SimulateKeyAction(SEL c) {
104     NSControl* control = [apps_search_box_controller_ searchTextField];
105     [apps_search_box_controller_ control:control
106                                 textView:nil
107                      doCommandBySelector:c];
108   }
109
110  protected:
111   // Overridden from app_list::AppListModelObserver:
112   virtual void OnAppListModelUsersChanged() OVERRIDE {
113     [apps_search_box_controller_ rebuildMenu];
114   }
115
116   virtual void OnAppListModelSigninStatusChanged() OVERRIDE {}
117
118   base::scoped_nsobject<TestAppsSearchBoxDelegate> delegate_;
119   base::scoped_nsobject<AppsSearchBoxController> apps_search_box_controller_;
120
121  private:
122   DISALLOW_COPY_AND_ASSIGN(AppsSearchBoxControllerTest);
123 };
124
125 TEST_VIEW(AppsSearchBoxControllerTest, [apps_search_box_controller_ view]);
126
127 // Test the search box initialization, and search input and clearing.
128 TEST_F(AppsSearchBoxControllerTest, SearchBoxModel) {
129   app_list::SearchBoxModel* model = [delegate_ searchBoxModel];
130   // Usually localized "Search".
131   const base::string16 hit_text(ASCIIToUTF16("hint"));
132   model->SetHintText(hit_text);
133   EXPECT_NSEQ(base::SysUTF16ToNSString(hit_text),
134       [[[apps_search_box_controller_ searchTextField] cell] placeholderString]);
135
136   const base::string16 search_text(ASCIIToUTF16("test"));
137   model->SetText(search_text);
138   EXPECT_NSEQ(base::SysUTF16ToNSString(search_text),
139               [[apps_search_box_controller_ searchTextField] stringValue]);
140   // Updates coming via the model should notify the delegate.
141   EXPECT_EQ(1, [delegate_ textChangeCount]);
142
143   // Updates from the view should update the model and notify the delegate.
144   [apps_search_box_controller_ clearSearch];
145   EXPECT_EQ(base::string16(), model->text());
146   EXPECT_NSEQ([NSString string],
147               [[apps_search_box_controller_ searchTextField] stringValue]);
148   EXPECT_EQ(2, [delegate_ textChangeCount]);
149
150   // Test pressing escape clears the search. First add some text.
151   model->SetText(search_text);
152   EXPECT_EQ(3, [delegate_ textChangeCount]);
153
154   EXPECT_NSEQ(base::SysUTF16ToNSString(search_text),
155               [[apps_search_box_controller_ searchTextField] stringValue]);
156   SimulateKeyAction(@selector(complete:));
157   EXPECT_NSEQ([NSString string],
158               [[apps_search_box_controller_ searchTextField] stringValue]);
159   EXPECT_EQ(4, [delegate_ textChangeCount]);
160 }
161
162 // Test the popup menu items when there is only one user..
163 TEST_F(AppsSearchBoxControllerTest, SearchBoxMenuSingleUser) {
164   // Set a single user. We need to set the delegate again because the
165   // AppListModel observer isn't hooked up in these tests.
166   [delegate_ appListModel]->SetUsers(app_list::AppListModel::Users(1));
167   [apps_search_box_controller_ setDelegate:delegate_];
168
169   NSPopUpButton* menu_control = [apps_search_box_controller_ menuControl];
170   EXPECT_TRUE([apps_search_box_controller_ appListMenu]);
171   ui::MenuModel* menu_model
172       = [apps_search_box_controller_ appListMenu]->menu_model();
173   // Add one to the item count to account for the blank, first item that Cocoa
174   // has in its popup menus.
175   EXPECT_EQ(menu_model->GetItemCount() + 1,
176             [[menu_control menu] numberOfItems]);
177
178   // All command ids should be less than |SELECT_PROFILE| as no user menu items
179   // are being shown.
180   for (int i = 0; i < menu_model->GetItemCount(); ++i)
181     EXPECT_LT(menu_model->GetCommandIdAt(i), AppListMenu::SELECT_PROFILE);
182
183   // The number of items should match the index that starts profile items.
184   EXPECT_EQ(AppListMenu::SELECT_PROFILE, menu_model->GetItemCount());
185 }
186
187 // Test the popup menu items for the multi-profile case.
188 TEST_F(AppsSearchBoxControllerTest, SearchBoxMenu) {
189   const app_list::AppListModel::Users& users =
190       [delegate_ appListModel]->users();
191   NSPopUpButton* menu_control = [apps_search_box_controller_ menuControl];
192   EXPECT_TRUE([apps_search_box_controller_ appListMenu]);
193   ui::MenuModel* menu_model
194       = [apps_search_box_controller_ appListMenu]->menu_model();
195   // Add one to the item count to account for the blank, first item that Cocoa
196   // has in its popup menus.
197   EXPECT_EQ(menu_model->GetItemCount() + 1,
198             [[menu_control menu] numberOfItems]);
199
200   ui::MenuModel* found_menu_model = menu_model;
201   int index;
202   MenuController* controller = [[menu_control menu] delegate];
203
204   // The first user item is an unchecked label.
205   EXPECT_TRUE(ui::MenuModel::GetModelAndIndexForCommandId(
206       AppListMenu::SELECT_PROFILE, &menu_model, &index));
207   EXPECT_EQ(found_menu_model, menu_model);
208   NSMenuItem* unchecked_user_item = [[menu_control menu] itemAtIndex:index + 1];
209   [controller validateUserInterfaceItem:unchecked_user_item];
210   // The profile name should be shown if there is no email available.
211   EXPECT_NSEQ(base::SysUTF16ToNSString(users[0].name),
212               [unchecked_user_item title]);
213   EXPECT_EQ(NSOffState, [unchecked_user_item state]);
214
215   // The second user item is a checked label because it is the active profile.
216   EXPECT_TRUE(ui::MenuModel::GetModelAndIndexForCommandId(
217       AppListMenu::SELECT_PROFILE + 1, &menu_model, &index));
218   EXPECT_EQ(found_menu_model, menu_model);
219   NSMenuItem* checked_user_item = [[menu_control menu] itemAtIndex:index + 1];
220   [controller validateUserInterfaceItem:checked_user_item];
221   // The email is shown when available.
222   EXPECT_NSEQ(base::SysUTF16ToNSString(users[1].email),
223               [checked_user_item title]);
224   EXPECT_EQ(NSOnState, [checked_user_item state]);
225
226   // A regular item should have just the label.
227   EXPECT_TRUE(ui::MenuModel::GetModelAndIndexForCommandId(
228       AppListMenu::SHOW_SETTINGS, &menu_model, &index));
229   EXPECT_EQ(found_menu_model, menu_model);
230   NSMenuItem* settings_item = [[menu_control menu] itemAtIndex:index + 1];
231   EXPECT_FALSE([settings_item view]);
232   EXPECT_NSEQ(base::SysUTF16ToNSString(menu_model->GetLabelAt(index)),
233               [settings_item title]);
234 }
235
236 // Test adding another user, and changing an existing one.
237 TEST_F(AppsSearchBoxControllerTest, SearchBoxMenuChangingUsers) {
238   app_list::AppListModel::Users users = [delegate_ appListModel]->users();
239   EXPECT_EQ(2u, users.size());
240   ui::MenuModel* menu_model
241       = [apps_search_box_controller_ appListMenu]->menu_model();
242   // Adding one to account for the empty item at index 0 in Cocoa popup menus.
243   int non_user_items = menu_model->GetItemCount() - users.size() + 1;
244
245   NSPopUpButton* menu_control = [apps_search_box_controller_ menuControl];
246   EXPECT_EQ(2, [[menu_control menu] numberOfItems] - non_user_items);
247   EXPECT_NSEQ(base::SysUTF16ToNSString(users[0].name),
248               [[[menu_control menu] itemAtIndex:1] title]);
249
250   users[0].name = ASCIIToUTF16("renamed user");
251   app_list::AppListModel::User new_user;
252   new_user.name = ASCIIToUTF16("user3");
253   users.push_back(new_user);
254   [delegate_ appListModel]->SetUsers(users);
255
256   // Should now be an extra item, and it should have correct titles.
257   EXPECT_EQ(3, [[menu_control menu] numberOfItems] - non_user_items);
258   EXPECT_NSEQ(base::SysUTF16ToNSString(users[0].name),
259               [[[menu_control menu] itemAtIndex:1] title]);
260   EXPECT_NSEQ(base::SysUTF16ToNSString(new_user.name),
261               [[[menu_control menu] itemAtIndex:3] title]);
262 }
263
264 }  // namespace test
265 }  // namespace app_list