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