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.
5 #import "chrome/browser/ui/cocoa/profiles/profile_chooser_controller.h"
7 #include "base/command_line.h"
8 #import "base/mac/foundation_util.h"
9 #include "base/mac/scoped_nsobject.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/strings/sys_string_conversions.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "chrome/browser/prefs/pref_service_syncable.h"
14 #include "chrome/browser/profiles/avatar_menu.h"
15 #include "chrome/browser/profiles/profile_info_cache.h"
16 #include "chrome/browser/services/gcm/fake_gcm_profile_service.h"
17 #include "chrome/browser/services/gcm/gcm_profile_service_factory.h"
18 #include "chrome/browser/signin/account_fetcher_service_factory.h"
19 #include "chrome/browser/signin/account_tracker_service_factory.h"
20 #include "chrome/browser/signin/chrome_signin_helper.h"
21 #include "chrome/browser/signin/fake_account_fetcher_service_builder.h"
22 #include "chrome/browser/signin/fake_profile_oauth2_token_service_builder.h"
23 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
24 #include "chrome/browser/signin/signin_manager_factory.h"
25 #include "chrome/browser/ui/browser.h"
26 #include "chrome/browser/ui/cocoa/cocoa_profile_test.h"
27 #include "chrome/common/chrome_switches.h"
28 #include "chrome/common/pref_names.h"
29 #include "components/signin/core/browser/fake_account_fetcher_service.h"
30 #include "components/signin/core/browser/fake_profile_oauth2_token_service.h"
31 #include "components/signin/core/browser/profile_oauth2_token_service.h"
32 #include "components/signin/core/browser/signin_manager.h"
33 #include "components/signin/core/common/profile_management_switches.h"
35 const std::string kGaiaId = "gaiaid-user@gmail.com";
36 const std::string kEmail = "user@gmail.com";
37 const std::string kSecondaryEmail = "user2@gmail.com";
38 const std::string kSecondaryGaiaId = "gaiaid-user2@gmail.com";
39 const std::string kLoginToken = "oauth2_login_token";
41 class ProfileChooserControllerTest : public CocoaProfileTest {
43 ProfileChooserControllerTest() {
44 TestingProfile::TestingFactories factories;
46 std::make_pair(ProfileOAuth2TokenServiceFactory::GetInstance(),
47 BuildFakeProfileOAuth2TokenService));
49 std::make_pair(AccountFetcherServiceFactory::GetInstance(),
50 FakeAccountFetcherServiceBuilder::BuildForTests));
51 AddTestingFactories(factories);
54 void SetUp() override {
55 CocoaProfileTest::SetUp();
57 ASSERT_TRUE(browser()->profile());
59 gcm::GCMProfileServiceFactory::GetInstance()->SetTestingFactory(
60 browser()->profile(), gcm::FakeGCMProfileService::Build);
62 testing_profile_manager()->
63 CreateTestingProfile("test1", scoped_ptr<PrefServiceSyncable>(),
64 base::ASCIIToUTF16("Test 1"), 0, std::string(),
66 testing_profile_manager()->
67 CreateTestingProfile("test2", scoped_ptr<PrefServiceSyncable>(),
68 base::ASCIIToUTF16("Test 2"), 1, std::string(),
69 TestingProfile::TestingFactories());
71 menu_ = new AvatarMenu(testing_profile_manager()->profile_info_cache(),
75 // There should be the default profile + two profiles we created.
76 EXPECT_EQ(3U, menu_->GetNumberOfItems());
79 void TearDown() override {
82 CocoaProfileTest::TearDown();
85 void StartProfileChooserController() {
86 StartProfileChooserControllerWithTutorialMode(profiles::TUTORIAL_MODE_NONE);
89 void StartProfileChooserControllerWithTutorialMode(
90 profiles::TutorialMode mode) {
91 NSRect frame = [test_window() frame];
92 NSPoint point = NSMakePoint(NSMidX(frame), NSMidY(frame));
93 controller_.reset([[ProfileChooserController alloc]
94 initWithBrowser:browser()
96 viewMode:profiles::BUBBLE_VIEW_MODE_PROFILE_CHOOSER
98 serviceType:signin::GAIA_SERVICE_TYPE_NONE]);
99 [controller_ showWindow:nil];
102 void AssertRightClickTutorialShown() {
103 NSArray* subviews = [[[controller() window] contentView] subviews];
104 ASSERT_EQ(2U, [subviews count]);
105 subviews = [[subviews objectAtIndex:0] subviews];
107 // There should be 4 views: the tutorial, the active profile card, a
108 // separator and the options view.
109 ASSERT_EQ(4U, [subviews count]);
111 // The tutorial is the topmost view, so the last in the array. It should
112 // contain 3 views: the title, the content text and the OK button.
113 NSArray* tutorialSubviews = [[subviews objectAtIndex:3] subviews];
114 ASSERT_EQ(3U, [tutorialSubviews count]);
116 NSTextField* tutorialTitle = base::mac::ObjCCastStrict<NSTextField>(
117 [tutorialSubviews objectAtIndex:2]);
118 EXPECT_GT([[tutorialTitle stringValue] length], 0U);
120 NSTextField* tutorialContent = base::mac::ObjCCastStrict<NSTextField>(
121 [tutorialSubviews objectAtIndex:1]);
122 EXPECT_GT([[tutorialContent stringValue] length], 0U);
124 NSButton* tutorialOKButton = base::mac::ObjCCastStrict<NSButton>(
125 [tutorialSubviews objectAtIndex:0]);
126 EXPECT_GT([[tutorialOKButton title] length], 0U);
129 void StartFastUserSwitcher() {
130 NSRect frame = [test_window() frame];
131 NSPoint point = NSMakePoint(NSMidX(frame), NSMidY(frame));
132 controller_.reset([[ProfileChooserController alloc]
133 initWithBrowser:browser()
135 viewMode:profiles::BUBBLE_VIEW_MODE_FAST_PROFILE_CHOOSER
136 tutorialMode:profiles::TUTORIAL_MODE_NONE
137 serviceType:signin::GAIA_SERVICE_TYPE_NONE]);
138 [controller_ showWindow:nil];
141 ProfileChooserController* controller() { return controller_; }
142 AvatarMenu* menu() { return menu_; }
145 base::scoped_nsobject<ProfileChooserController> controller_;
147 // Weak; owned by |controller_|.
150 DISALLOW_COPY_AND_ASSIGN(ProfileChooserControllerTest);
153 TEST_F(ProfileChooserControllerTest, InitialLayoutWithNewMenu) {
154 switches::EnableNewAvatarMenuForTesting(
155 base::CommandLine::ForCurrentProcess());
156 StartProfileChooserController();
158 NSArray* subviews = [[[controller() window] contentView] subviews];
159 ASSERT_EQ(2U, [subviews count]);
160 subviews = [[subviews objectAtIndex:0] subviews];
162 // Three profiles means we should have one active card, one separator and
163 // one option buttons view. We also have an update promo for the new avatar
165 // TODO(noms): Enforcing 4U fails on the waterfall debug bots, but it's not
166 // reproducible anywhere else.
167 ASSERT_GE([subviews count], 3U);
169 // There should be two buttons and a separator in the option buttons view.
170 NSArray* buttonSubviews = [[subviews objectAtIndex:0] subviews];
171 ASSERT_EQ(3U, [buttonSubviews count]);
173 // There should be an incognito button.
174 NSButton* incognitoButton =
175 base::mac::ObjCCast<NSButton>([buttonSubviews objectAtIndex:0]);
176 EXPECT_EQ(@selector(goIncognito:), [incognitoButton action]);
177 EXPECT_EQ(controller(), [incognitoButton target]);
179 // There should be a separator.
180 EXPECT_TRUE([[subviews objectAtIndex:1] isKindOfClass:[NSBox class]]);
182 // There should be a user switcher button.
183 NSButton* userSwitcherButton =
184 base::mac::ObjCCast<NSButton>([buttonSubviews objectAtIndex:2]);
185 EXPECT_EQ(@selector(showUserManager:), [userSwitcherButton action]);
186 EXPECT_EQ(controller(), [userSwitcherButton target]);
188 // There should be a separator.
189 EXPECT_TRUE([[subviews objectAtIndex:1] isKindOfClass:[NSBox class]]);
191 // There should be the profile avatar, name and links container in the active
192 // card view. The links displayed in the container are checked separately.
193 NSArray* activeCardSubviews = [[subviews objectAtIndex:2] subviews];
194 ASSERT_EQ(3U, [activeCardSubviews count]);
197 NSView* activeProfileImage = [activeCardSubviews objectAtIndex:2];
198 EXPECT_TRUE([activeProfileImage isKindOfClass:[NSButton class]]);
201 NSView* activeProfileName = [activeCardSubviews objectAtIndex:1];
202 EXPECT_TRUE([activeProfileName isKindOfClass:[NSButton class]]);
203 EXPECT_EQ(menu()->GetItemAt(0).name, base::SysNSStringToUTF16(
204 [base::mac::ObjCCast<NSButton>(activeProfileName) title]));
206 // Profile links. This is a local profile, so there should be a signin button
207 // and a signin promo.
208 NSArray* linksSubviews = [[activeCardSubviews objectAtIndex:0] subviews];
209 ASSERT_EQ(2U, [linksSubviews count]);
210 NSButton* link = base::mac::ObjCCast<NSButton>(
211 [linksSubviews objectAtIndex:0]);
212 EXPECT_EQ(@selector(showInlineSigninPage:), [link action]);
213 EXPECT_EQ(controller(), [link target]);
215 NSTextField* promo = base::mac::ObjCCast<NSTextField>(
216 [linksSubviews objectAtIndex:1]);
217 EXPECT_GT([[promo stringValue] length], 0U);
220 TEST_F(ProfileChooserControllerTest, RightClickTutorialShownAfterWelcome) {
221 switches::EnableNewAvatarMenuForTesting(
222 base::CommandLine::ForCurrentProcess());
223 // The welcome upgrade tutorial takes precedence so show it then dismiss it.
224 // The right click tutorial should be shown right away.
225 StartProfileChooserControllerWithTutorialMode(
226 profiles::TUTORIAL_MODE_WELCOME_UPGRADE);
228 [controller() dismissTutorial:nil];
229 AssertRightClickTutorialShown();
232 TEST_F(ProfileChooserControllerTest, RightClickTutorialShownAfterReopen) {
233 switches::EnableNewAvatarMenuForTesting(
234 base::CommandLine::ForCurrentProcess());
235 // The welcome upgrade tutorial takes precedence so show it then close the
236 // menu. Reopening the menu should show the tutorial.
237 StartProfileChooserController();
239 [controller() close];
240 StartProfileChooserController();
241 AssertRightClickTutorialShown();
243 // The tutorial must be manually dismissed so it should still be shown after
244 // closing and reopening the menu,
245 [controller() close];
246 StartProfileChooserController();
247 AssertRightClickTutorialShown();
250 TEST_F(ProfileChooserControllerTest, RightClickTutorialNotShownAfterDismiss) {
251 switches::EnableNewAvatarMenuForTesting(
252 base::CommandLine::ForCurrentProcess());
253 // The welcome upgrade tutorial takes precedence so show it then close the
254 // menu. Reopening the menu should show the tutorial.
255 StartProfileChooserController();
257 [controller() close];
258 StartProfileChooserControllerWithTutorialMode(
259 profiles::TUTORIAL_MODE_RIGHT_CLICK_SWITCHING);
260 AssertRightClickTutorialShown();
262 // Dismissing the tutorial should prevent it from being shown forever.
263 [controller() dismissTutorial:nil];
264 NSArray* subviews = [[[controller() window] contentView] subviews];
265 ASSERT_EQ(2U, [subviews count]);
266 subviews = [[subviews objectAtIndex:0] subviews];
268 // There should be 3 views since there's no tutorial
269 ASSERT_EQ(3U, [subviews count]);
271 // Closing and reopening the menu shouldn't show the tutorial.
272 [controller() close];
273 StartProfileChooserControllerWithTutorialMode(
274 profiles::TUTORIAL_MODE_RIGHT_CLICK_SWITCHING);
275 subviews = [[[controller() window] contentView] subviews];
276 ASSERT_EQ(2U, [subviews count]);
277 subviews = [[subviews objectAtIndex:0] subviews];
279 // There should be 3 views since there's no tutorial
280 ASSERT_EQ(3U, [subviews count]);
283 TEST_F(ProfileChooserControllerTest, OtherProfilesSortedAlphabetically) {
284 switches::EnableNewAvatarMenuForTesting(
285 base::CommandLine::ForCurrentProcess());
287 // Add two extra profiles, to make sure sorting is alphabetical and not
288 // by order of creation.
289 testing_profile_manager()->
290 CreateTestingProfile("test3", scoped_ptr<PrefServiceSyncable>(),
291 base::ASCIIToUTF16("New Profile"), 1, std::string(),
292 TestingProfile::TestingFactories());
293 testing_profile_manager()->
294 CreateTestingProfile("test4", scoped_ptr<PrefServiceSyncable>(),
295 base::ASCIIToUTF16("Another Test"), 1, std::string(),
296 TestingProfile::TestingFactories());
297 StartFastUserSwitcher();
299 NSArray* subviews = [[[controller() window] contentView] subviews];
300 ASSERT_EQ(2U, [subviews count]);
301 subviews = [[subviews objectAtIndex:0] subviews];
302 NSString* sortedNames[] = { @"Another Test",
306 // There are four "other" profiles, each with a button and a separator.
307 ASSERT_EQ([subviews count], 8U);
308 // There should be four "other profiles" items, sorted alphabetically. The
309 // "other profiles" start at index 2 (after the option buttons view and its
310 // separator), and each have a separator. We need to iterate through the
311 // profiles in the order displayed in the bubble, which is opposite from the
313 int sortedNameIndex = 0;
314 for (int i = 7; i > 0; i -= 2) {
315 // The item at index i is the separator.
316 NSButton* button = base::mac::ObjCCast<NSButton>(
317 [subviews objectAtIndex:i-1]);
319 [[button title] isEqualToString:sortedNames[sortedNameIndex++]]);
323 TEST_F(ProfileChooserControllerTest,
324 LocalProfileActiveCardLinksWithNewMenu) {
325 switches::EnableNewAvatarMenuForTesting(
326 base::CommandLine::ForCurrentProcess());
327 StartProfileChooserController();
328 NSArray* subviews = [[[controller() window] contentView] subviews];
329 ASSERT_EQ(2U, [subviews count]);
330 subviews = [[subviews objectAtIndex:0] subviews];
331 NSArray* activeCardSubviews = [[subviews objectAtIndex:2] subviews];
332 NSArray* activeCardLinks = [[activeCardSubviews objectAtIndex:0] subviews];
334 ASSERT_EQ(2U, [activeCardLinks count]);
336 // There should be a sign in button.
337 NSButton* link = base::mac::ObjCCast<NSButton>(
338 [activeCardLinks objectAtIndex:0]);
339 EXPECT_EQ(@selector(showInlineSigninPage:), [link action]);
340 EXPECT_EQ(controller(), [link target]);
342 // Local profiles have a signin promo.
343 NSTextField* promo = base::mac::ObjCCast<NSTextField>(
344 [activeCardLinks objectAtIndex:1]);
345 EXPECT_GT([[promo stringValue] length], 0U);
348 TEST_F(ProfileChooserControllerTest,
349 SignedInProfileActiveCardLinksWithAccountConsistency) {
350 switches::EnableAccountConsistencyForTesting(
351 base::CommandLine::ForCurrentProcess());
352 // Sign in the first profile.
353 ProfileInfoCache* cache = testing_profile_manager()->profile_info_cache();
354 cache->SetAuthInfoOfProfileAtIndex(0, kGaiaId, base::ASCIIToUTF16(kEmail));
356 StartProfileChooserController();
357 NSArray* subviews = [[[controller() window] contentView] subviews];
358 ASSERT_EQ(2U, [subviews count]);
359 subviews = [[subviews objectAtIndex:0] subviews];
360 NSArray* activeCardSubviews = [[subviews objectAtIndex:2] subviews];
361 NSArray* activeCardLinks = [[activeCardSubviews objectAtIndex:0] subviews];
363 // There is one link: manage accounts.
364 ASSERT_EQ(1U, [activeCardLinks count]);
365 NSButton* manageAccountsLink =
366 base::mac::ObjCCast<NSButton>([activeCardLinks objectAtIndex:0]);
367 EXPECT_EQ(@selector(showAccountManagement:), [manageAccountsLink action]);
368 EXPECT_EQ(controller(), [manageAccountsLink target]);
371 TEST_F(ProfileChooserControllerTest,
372 SignedInProfileActiveCardLinksWithNewMenu) {
373 switches::EnableNewAvatarMenuForTesting(
374 base::CommandLine::ForCurrentProcess());
375 // Sign in the first profile.
376 ProfileInfoCache* cache = testing_profile_manager()->profile_info_cache();
377 cache->SetAuthInfoOfProfileAtIndex(0, kGaiaId, base::ASCIIToUTF16(kEmail));
379 StartProfileChooserController();
380 NSArray* subviews = [[[controller() window] contentView] subviews];
381 ASSERT_EQ(2U, [subviews count]);
382 subviews = [[subviews objectAtIndex:0] subviews];
383 NSArray* activeCardSubviews = [[subviews objectAtIndex:2] subviews];
384 NSArray* activeCardLinks = [[activeCardSubviews objectAtIndex:0] subviews];
386 // There is one disabled button with the user's email.
387 ASSERT_EQ(1U, [activeCardLinks count]);
388 NSButton* emailButton =
389 base::mac::ObjCCast<NSButton>([activeCardLinks objectAtIndex:0]);
390 EXPECT_EQ(kEmail, base::SysNSStringToUTF8([emailButton title]));
391 EXPECT_EQ(nil, [emailButton action]);
392 EXPECT_FALSE([emailButton isEnabled]);
395 TEST_F(ProfileChooserControllerTest, AccountManagementLayout) {
396 switches::EnableAccountConsistencyForTesting(
397 base::CommandLine::ForCurrentProcess());
398 // Sign in the first profile.
399 ProfileInfoCache* cache = testing_profile_manager()->profile_info_cache();
400 cache->SetAuthInfoOfProfileAtIndex(0, kGaiaId, base::ASCIIToUTF16(kEmail));
402 // Mark that we are using the profile name on purpose, so that we don't
403 // fallback to testing the algorithm that chooses which default name
405 cache->SetProfileIsUsingDefaultNameAtIndex(0, false);
407 // Set up the AccountTrackerService, signin manager and the OAuth2Tokens.
408 Profile* profile = browser()->profile();
409 AccountTrackerServiceFactory::GetForProfile(profile)
410 ->SeedAccountInfo(kGaiaId, kEmail);
411 AccountTrackerServiceFactory::GetForProfile(profile)
412 ->SeedAccountInfo(kSecondaryGaiaId, kSecondaryEmail);
413 SigninManagerFactory::GetForProfile(profile)
414 ->SetAuthenticatedAccountInfo(kGaiaId, kEmail);
415 std::string account_id =
416 SigninManagerFactory::GetForProfile(profile)->GetAuthenticatedAccountId();
417 ProfileOAuth2TokenServiceFactory::GetForProfile(profile)
418 ->UpdateCredentials(account_id, kLoginToken);
419 account_id = AccountTrackerServiceFactory::GetForProfile(profile)
420 ->PickAccountIdForAccount(kSecondaryGaiaId, kSecondaryEmail);
421 ProfileOAuth2TokenServiceFactory::GetForProfile(profile)
422 ->UpdateCredentials(account_id, kLoginToken);
424 StartProfileChooserController();
425 [controller() initMenuContentsWithView:
426 profiles::BUBBLE_VIEW_MODE_ACCOUNT_MANAGEMENT];
428 NSArray* subviews = [[[controller() window] contentView] subviews];
429 ASSERT_EQ(2U, [subviews count]);
430 subviews = [[subviews objectAtIndex:0] subviews];
432 // There should be one active card, one accounts container, two separators
433 // and one option buttons view.
434 ASSERT_EQ(5U, [subviews count]);
436 // There should be three buttons and two separators in the option
438 NSArray* buttonSubviews = [[subviews objectAtIndex:0] subviews];
439 ASSERT_EQ(3U, [buttonSubviews count]);
441 // There should be a separator.
442 EXPECT_TRUE([[buttonSubviews objectAtIndex:1] isKindOfClass:[NSBox class]]);
444 // There should be an incognito button.
445 NSButton* incognitoButton =
446 base::mac::ObjCCast<NSButton>([buttonSubviews objectAtIndex:0]);
447 EXPECT_EQ(@selector(goIncognito:), [incognitoButton action]);
448 EXPECT_EQ(controller(), [incognitoButton target]);
450 // There should be a separator.
451 EXPECT_TRUE([[subviews objectAtIndex:3] isKindOfClass:[NSBox class]]);
453 // There should be a user switcher button.
454 NSButton* userSwitcherButton =
455 base::mac::ObjCCast<NSButton>([buttonSubviews objectAtIndex:2]);
456 EXPECT_EQ(@selector(showUserManager:), [userSwitcherButton action]);
457 EXPECT_EQ(controller(), [userSwitcherButton target]);
459 // In the accounts view, there should be the account list container
460 // accounts and one "add accounts" button.
461 NSArray* accountsSubviews = [[subviews objectAtIndex:2] subviews];
462 ASSERT_EQ(2U, [accountsSubviews count]);
464 NSButton* addAccountsButton =
465 base::mac::ObjCCast<NSButton>([accountsSubviews objectAtIndex:0]);
466 EXPECT_EQ(@selector(addAccount:), [addAccountsButton action]);
467 EXPECT_EQ(controller(), [addAccountsButton target]);
469 // There should be two accounts in the account list container.
470 NSArray* accountsListSubviews = [[accountsSubviews objectAtIndex:1] subviews];
471 ASSERT_EQ(2U, [accountsListSubviews count]);
473 NSButton* genericAccount =
474 base::mac::ObjCCast<NSButton>([accountsListSubviews objectAtIndex:0]);
475 NSButton* genericAccountDelete = base::mac::ObjCCast<NSButton>(
476 [[genericAccount subviews] objectAtIndex:0]);
477 EXPECT_EQ(@selector(showAccountRemovalView:), [genericAccountDelete action]);
478 EXPECT_EQ(controller(), [genericAccountDelete target]);
479 EXPECT_NE(-1, [genericAccountDelete tag]);
481 // Primary accounts are always last.
482 NSButton* primaryAccount =
483 base::mac::ObjCCast<NSButton>([accountsListSubviews objectAtIndex:1]);
484 NSButton* primaryAccountDelete = base::mac::ObjCCast<NSButton>(
485 [[primaryAccount subviews] objectAtIndex:0]);
486 EXPECT_EQ(@selector(showAccountRemovalView:), [primaryAccountDelete action]);
487 EXPECT_EQ(controller(), [primaryAccountDelete target]);
488 EXPECT_EQ(-1, [primaryAccountDelete tag]);
490 // There should be another separator.
491 EXPECT_TRUE([[subviews objectAtIndex:3] isKindOfClass:[NSBox class]]);
493 // There should be the profile avatar, name and a "hide accounts" link
494 // container in the active card view.
495 NSArray* activeCardSubviews = [[subviews objectAtIndex:4] subviews];
496 ASSERT_EQ(3U, [activeCardSubviews count]);
499 NSView* activeProfileImage = [activeCardSubviews objectAtIndex:2];
500 EXPECT_TRUE([activeProfileImage isKindOfClass:[NSButton class]]);
503 NSView* activeProfileName = [activeCardSubviews objectAtIndex:1];
504 EXPECT_TRUE([activeProfileName isKindOfClass:[NSButton class]]);
505 EXPECT_EQ(menu()->GetItemAt(0).name, base::SysNSStringToUTF16(
506 [base::mac::ObjCCast<NSButton>(activeProfileName) title]));
508 // Profile links. This is a local profile, so there should be a signin button.
509 NSArray* linksSubviews = [[activeCardSubviews objectAtIndex:0] subviews];
510 ASSERT_EQ(1U, [linksSubviews count]);
511 NSButton* link = base::mac::ObjCCast<NSButton>(
512 [linksSubviews objectAtIndex:0]);
513 EXPECT_EQ(@selector(hideAccountManagement:), [link action]);
514 EXPECT_EQ(controller(), [link target]);
517 TEST_F(ProfileChooserControllerTest, SignedInProfileLockDisabled) {
518 switches::EnableNewProfileManagementForTesting(
519 base::CommandLine::ForCurrentProcess());
520 // Sign in the first profile.
521 ProfileInfoCache* cache = testing_profile_manager()->profile_info_cache();
522 cache->SetAuthInfoOfProfileAtIndex(0, kGaiaId, base::ASCIIToUTF16(kEmail));
523 // The preference, not the email, determines whether the profile can lock.
524 browser()->profile()->GetPrefs()->SetString(
525 prefs::kGoogleServicesHostedDomain, "chromium.org");
527 StartProfileChooserController();
528 NSArray* subviews = [[[controller() window] contentView] subviews];
529 ASSERT_EQ(2U, [subviews count]);
530 subviews = [[subviews objectAtIndex:0] subviews];
532 // There will be two buttons and one separators in the option buttons view.
533 NSArray* buttonSubviews = [[subviews objectAtIndex:0] subviews];
534 ASSERT_EQ(3U, [buttonSubviews count]);
536 // The last button should not be the lock button.
537 NSButton* lastButton =
538 base::mac::ObjCCast<NSButton>([buttonSubviews objectAtIndex:0]);
539 ASSERT_TRUE(lastButton);
540 EXPECT_NE(@selector(lockProfile:), [lastButton action]);
543 TEST_F(ProfileChooserControllerTest, SignedInProfileLockEnabled) {
544 switches::EnableNewProfileManagementForTesting(
545 base::CommandLine::ForCurrentProcess());
546 // Sign in the first profile.
547 ProfileInfoCache* cache = testing_profile_manager()->profile_info_cache();
548 cache->SetAuthInfoOfProfileAtIndex(0, kGaiaId, base::ASCIIToUTF16(kEmail));
549 // The preference, not the email, determines whether the profile can lock.
550 browser()->profile()->GetPrefs()->SetString(
551 prefs::kGoogleServicesHostedDomain, "google.com");
552 // Lock is only available where a supervised user is present.
553 cache->SetSupervisedUserIdOfProfileAtIndex(1, kEmail);
555 StartProfileChooserController();
556 NSArray* subviews = [[[controller() window] contentView] subviews];
557 ASSERT_EQ(2U, [subviews count]);
558 subviews = [[subviews objectAtIndex:0] subviews];
560 // There will be three buttons and two separators in the option buttons view.
561 NSArray* buttonSubviews = [[subviews objectAtIndex:0] subviews];
562 ASSERT_EQ(5U, [buttonSubviews count]);
564 // There should be a lock button.
565 NSButton* lockButton =
566 base::mac::ObjCCast<NSButton>([buttonSubviews objectAtIndex:0]);
567 ASSERT_TRUE(lockButton);
568 EXPECT_EQ(@selector(lockProfile:), [lockButton action]);
569 EXPECT_EQ(controller(), [lockButton target]);
570 EXPECT_TRUE([lockButton isEnabled]);