apps_search_box_controller_unittest.mm revision eb525c5499e34cc9c4b825d6d9e75bb07cc06ace
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#import "ui/app_list/cocoa/current_user_menu_item_view.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/test/ui_cocoa_test_helper.h"
17
18@interface TestAppsSearchBoxDelegate : NSObject<AppsSearchBoxDelegate> {
19 @private
20  app_list::SearchBoxModel searchBoxModel_;
21  app_list::test::AppListTestViewDelegate appListDelegate_;
22  int textChangeCount_;
23}
24
25@property(assign, nonatomic) int textChangeCount;
26
27@end
28
29@implementation TestAppsSearchBoxDelegate
30
31@synthesize textChangeCount = textChangeCount_;
32
33- (app_list::SearchBoxModel*)searchBoxModel {
34  return &searchBoxModel_;
35}
36
37- (app_list::AppListViewDelegate*)appListDelegate {
38  return &appListDelegate_;
39}
40
41- (BOOL)control:(NSControl*)control
42               textView:(NSTextView*)textView
43    doCommandBySelector:(SEL)command {
44  return NO;
45}
46
47- (void)modelTextDidChange {
48  ++textChangeCount_;
49}
50
51- (CGFloat)bubbleCornerRadius {
52  return 3;
53}
54
55@end
56
57namespace app_list {
58namespace test {
59
60class AppsSearchBoxControllerTest : public ui::CocoaTest {
61 public:
62  AppsSearchBoxControllerTest() {
63    Init();
64  }
65
66  virtual void SetUp() OVERRIDE {
67    apps_search_box_controller_.reset(
68        [[AppsSearchBoxController alloc] initWithFrame:
69            NSMakeRect(0, 0, 400, 100)]);
70    delegate_.reset([[TestAppsSearchBoxDelegate alloc] init]);
71    [apps_search_box_controller_ setDelegate:delegate_];
72
73    ui::CocoaTest::SetUp();
74    [[test_window() contentView] addSubview:[apps_search_box_controller_ view]];
75  }
76
77  virtual void TearDown() OVERRIDE {
78    [apps_search_box_controller_ setDelegate:nil];
79    ui::CocoaTest::TearDown();
80  }
81
82  void SimulateKeyAction(SEL c) {
83    NSControl* control = [apps_search_box_controller_ searchTextField];
84    [apps_search_box_controller_ control:control
85                                textView:nil
86                     doCommandBySelector:c];
87  }
88
89 protected:
90  base::scoped_nsobject<TestAppsSearchBoxDelegate> delegate_;
91  base::scoped_nsobject<AppsSearchBoxController> apps_search_box_controller_;
92
93 private:
94  DISALLOW_COPY_AND_ASSIGN(AppsSearchBoxControllerTest);
95};
96
97TEST_VIEW(AppsSearchBoxControllerTest, [apps_search_box_controller_ view]);
98
99// Test the search box initialization, and search input and clearing.
100TEST_F(AppsSearchBoxControllerTest, SearchBoxModel) {
101  app_list::SearchBoxModel* model = [delegate_ searchBoxModel];
102  // Usually localized "Search".
103  const base::string16 hit_text(ASCIIToUTF16("hint"));
104  model->SetHintText(hit_text);
105  EXPECT_NSEQ(base::SysUTF16ToNSString(hit_text),
106      [[[apps_search_box_controller_ searchTextField] cell] placeholderString]);
107
108  const base::string16 search_text(ASCIIToUTF16("test"));
109  model->SetText(search_text);
110  EXPECT_NSEQ(base::SysUTF16ToNSString(search_text),
111              [[apps_search_box_controller_ searchTextField] stringValue]);
112  // Updates coming via the model should not notify the delegate.
113  EXPECT_EQ(0, [delegate_ textChangeCount]);
114
115  // Updates from the view should update the model and notify the delegate.
116  [apps_search_box_controller_ clearSearch];
117  EXPECT_EQ(base::string16(), model->text());
118  EXPECT_NSEQ([NSString string],
119              [[apps_search_box_controller_ searchTextField] stringValue]);
120  EXPECT_EQ(1, [delegate_ textChangeCount]);
121
122  // Test pressing escape clears the search.
123  model->SetText(search_text);
124  EXPECT_NSEQ(base::SysUTF16ToNSString(search_text),
125              [[apps_search_box_controller_ searchTextField] stringValue]);
126  SimulateKeyAction(@selector(complete:));
127  EXPECT_NSEQ([NSString string],
128              [[apps_search_box_controller_ searchTextField] stringValue]);
129  EXPECT_EQ(2, [delegate_ textChangeCount]);
130}
131
132// Test the popup menu items.
133TEST_F(AppsSearchBoxControllerTest, SearchBoxMenu) {
134  NSPopUpButton* menu_control = [apps_search_box_controller_ menuControl];
135  EXPECT_TRUE([apps_search_box_controller_ appListMenu]);
136  ui::MenuModel* menu_model
137      = [apps_search_box_controller_ appListMenu]->menu_model();
138  // Add one to the item count to account for the blank, first item that Cocoa
139  // has in its popup menus.
140  EXPECT_EQ(menu_model->GetItemCount() + 1,
141            [[menu_control menu] numberOfItems]);
142
143  // The CURRENT_USER item should contain our custom view.
144  ui::MenuModel* found_menu_model = menu_model;
145  int index;
146  EXPECT_TRUE(ui::MenuModel::GetModelAndIndexForCommandId(
147      AppListMenu::CURRENT_USER, &menu_model, &index));
148  EXPECT_EQ(found_menu_model, menu_model);
149  NSMenuItem* current_user_item = [[menu_control menu] itemAtIndex:index + 1];
150  EXPECT_TRUE([current_user_item view]);
151
152  // A regular item should have just the label.
153  EXPECT_TRUE(ui::MenuModel::GetModelAndIndexForCommandId(
154      AppListMenu::SHOW_SETTINGS, &menu_model, &index));
155  EXPECT_EQ(found_menu_model, menu_model);
156  NSMenuItem* settings_item = [[menu_control menu] itemAtIndex:index + 1];
157  EXPECT_FALSE([settings_item view]);
158  EXPECT_NSEQ(base::SysUTF16ToNSString(menu_model->GetLabelAt(index)),
159              [settings_item title]);
160}
161
162// Test initialization and display of the custom menu item that shows the
163// currently signed-in user. This is a non-interactive view.
164class AppsSearchBoxCustomMenuItemTest : public ui::CocoaTest {
165 public:
166  AppsSearchBoxCustomMenuItemTest() {
167    Init();
168  }
169
170  virtual void SetUp() OVERRIDE {
171    scoped_ptr<AppListViewDelegate> delegate(new AppListTestViewDelegate);
172    current_user_menu_item_.reset([[[CurrentUserMenuItemView alloc]
173        initWithDelegate:delegate.get()] retain]);
174    ui::CocoaTest::SetUp();
175    [[test_window() contentView] addSubview:current_user_menu_item_];
176  }
177
178 protected:
179  base::scoped_nsobject<NSView> current_user_menu_item_;
180
181 private:
182  DISALLOW_COPY_AND_ASSIGN(AppsSearchBoxCustomMenuItemTest);
183};
184
185TEST_VIEW(AppsSearchBoxCustomMenuItemTest, current_user_menu_item_);
186
187}  // namespace test
188}  // namespace app_list
189