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/profiles/avatar_menu.h"
14 #include "chrome/browser/profiles/profile_info_cache.h"
15 #include "chrome/browser/services/gcm/fake_gcm_profile_service.h"
16 #include "chrome/browser/services/gcm/gcm_profile_service_factory.h"
17 #include "chrome/browser/signin/account_fetcher_service_factory.h"
18 #include "chrome/browser/signin/account_tracker_service_factory.h"
19 #include "chrome/browser/signin/chrome_signin_helper.h"
20 #include "chrome/browser/signin/fake_account_fetcher_service_builder.h"
21 #include "chrome/browser/signin/fake_profile_oauth2_token_service_builder.h"
22 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
23 #include "chrome/browser/signin/signin_manager_factory.h"
24 #include "chrome/browser/ui/browser.h"
25 #include "chrome/browser/ui/cocoa/cocoa_profile_test.h"
26 #include "chrome/common/chrome_switches.h"
27 #include "chrome/common/pref_names.h"
28 #include "components/signin/core/browser/fake_account_fetcher_service.h"
29 #include "components/signin/core/browser/fake_profile_oauth2_token_service.h"
30 #include "components/signin/core/browser/profile_oauth2_token_service.h"
31 #include "components/signin/core/browser/signin_manager.h"
32 #include "components/signin/core/common/profile_management_switches.h"
33 #include "components/syncable_prefs/pref_service_syncable.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()->CreateTestingProfile(
63 "test1", scoped_ptr<syncable_prefs::PrefServiceSyncable>(),
64 base::ASCIIToUTF16("Test 1"), 0, std::string(), testing_factories());
65 testing_profile_manager()->CreateTestingProfile(
66 "test2", scoped_ptr<syncable_prefs::PrefServiceSyncable>(),
67 base::ASCIIToUTF16("Test 2"), 1, std::string(),
68 TestingProfile::TestingFactories());
70 menu_ = new AvatarMenu(testing_profile_manager()->profile_info_cache(),
74 // There should be the default profile + two profiles we created.
75 EXPECT_EQ(3U, menu_->GetNumberOfItems());
78 void TearDown() override {
81 CocoaProfileTest::TearDown();
84 void StartProfileChooserController() {
85 StartProfileChooserControllerWithTutorialMode(profiles::TUTORIAL_MODE_NONE);
88 void StartProfileChooserControllerWithTutorialMode(
89 profiles::TutorialMode mode) {
90 NSRect frame = [test_window() frame];
91 NSPoint point = NSMakePoint(NSMidX(frame), NSMidY(frame));
92 controller_.reset([[ProfileChooserController alloc]
93 initWithBrowser:browser()
95 viewMode:profiles::BUBBLE_VIEW_MODE_PROFILE_CHOOSER
97 serviceType:signin::GAIA_SERVICE_TYPE_NONE]);
98 [controller_ showWindow:nil];
101 void AssertRightClickTutorialShown() {
102 NSArray* subviews = [[[controller() window] contentView] subviews];
103 ASSERT_EQ(2U, [subviews count]);
104 subviews = [[subviews objectAtIndex:0] subviews];
106 // There should be 4 views: the tutorial, the active profile card, a
107 // separator and the options view.
108 ASSERT_EQ(4U, [subviews count]);
110 // The tutorial is the topmost view, so the last in the array. It should
111 // contain 3 views: the title, the content text and the OK button.
112 NSArray* tutorialSubviews = [[subviews objectAtIndex:3] subviews];
113 ASSERT_EQ(3U, [tutorialSubviews count]);
115 NSTextField* tutorialTitle = base::mac::ObjCCastStrict<NSTextField>(
116 [tutorialSubviews objectAtIndex:2]);
117 EXPECT_GT([[tutorialTitle stringValue] length], 0U);
119 NSTextField* tutorialContent = base::mac::ObjCCastStrict<NSTextField>(
120 [tutorialSubviews objectAtIndex:1]);
121 EXPECT_GT([[tutorialContent stringValue] length], 0U);
123 NSButton* tutorialOKButton = base::mac::ObjCCastStrict<NSButton>(
124 [tutorialSubviews objectAtIndex:0]);
125 EXPECT_GT([[tutorialOKButton title] length], 0U);
128 void StartFastUserSwitcher() {
129 NSRect frame = [test_window() frame];
130 NSPoint point = NSMakePoint(NSMidX(frame), NSMidY(frame));
131 controller_.reset([[ProfileChooserController alloc]
132 initWithBrowser:browser()
134 viewMode:profiles::BUBBLE_VIEW_MODE_FAST_PROFILE_CHOOSER
135 tutorialMode:profiles::TUTORIAL_MODE_NONE
136 serviceType:signin::GAIA_SERVICE_TYPE_NONE]);
137 [controller_ showWindow:nil];
140 ProfileChooserController* controller() { return controller_; }
141 AvatarMenu* menu() { return menu_; }
144 base::scoped_nsobject<ProfileChooserController> controller_;
146 // Weak; owned by |controller_|.
149 DISALLOW_COPY_AND_ASSIGN(ProfileChooserControllerTest);
152 TEST_F(ProfileChooserControllerTest, InitialLayoutWithNewMenu) {
153 switches::EnableNewAvatarMenuForTesting(
154 base::CommandLine::ForCurrentProcess());
155 StartProfileChooserController();
157 NSArray* subviews = [[[controller() window] contentView] subviews];
158 ASSERT_EQ(2U, [subviews count]);
159 subviews = [[subviews objectAtIndex:0] subviews];
161 // Three profiles means we should have one active card, one separator and
162 // one option buttons view. We also have an update promo for the new avatar
164 // TODO(noms): Enforcing 4U fails on the waterfall debug bots, but it's not
165 // reproducible anywhere else.
166 ASSERT_GE([subviews count], 3U);
168 // There should be two buttons and a separator in the option buttons view.
169 NSArray* buttonSubviews = [[subviews objectAtIndex:0] subviews];
170 ASSERT_EQ(3U, [buttonSubviews count]);
172 // There should be an incognito button.
173 NSButton* incognitoButton =
174 base::mac::ObjCCast<NSButton>([buttonSubviews objectAtIndex:0]);
175 EXPECT_EQ(@selector(goIncognito:), [incognitoButton action]);
176 EXPECT_EQ(controller(), [incognitoButton target]);
178 // There should be a separator.
179 EXPECT_TRUE([[subviews objectAtIndex:1] isKindOfClass:[NSBox class]]);
181 // There should be a user switcher button.
182 NSButton* userSwitcherButton =
183 base::mac::ObjCCast<NSButton>([buttonSubviews objectAtIndex:2]);
184 EXPECT_EQ(@selector(showUserManager:), [userSwitcherButton action]);
185 EXPECT_EQ(controller(), [userSwitcherButton target]);
187 // There should be a separator.
188 EXPECT_TRUE([[subviews objectAtIndex:1] isKindOfClass:[NSBox class]]);
190 // There should be the profile avatar, name and links container in the active
191 // card view. The links displayed in the container are checked separately.
192 NSArray* activeCardSubviews = [[subviews objectAtIndex:2] subviews];
193 ASSERT_EQ(3U, [activeCardSubviews count]);
196 NSView* activeProfileImage = [activeCardSubviews objectAtIndex:2];
197 EXPECT_TRUE([activeProfileImage isKindOfClass:[NSButton class]]);
200 NSView* activeProfileName = [activeCardSubviews objectAtIndex:1];
201 EXPECT_TRUE([activeProfileName isKindOfClass:[NSButton class]]);
202 EXPECT_EQ(menu()->GetItemAt(0).name, base::SysNSStringToUTF16(
203 [base::mac::ObjCCast<NSButton>(activeProfileName) title]));
205 // Profile links. This is a local profile, so there should be a signin button
206 // and a signin promo.
207 NSArray* linksSubviews = [[activeCardSubviews objectAtIndex:0] subviews];
208 ASSERT_EQ(2U, [linksSubviews count]);
209 NSButton* link = base::mac::ObjCCast<NSButton>(
210 [linksSubviews objectAtIndex:0]);
211 EXPECT_EQ(@selector(showInlineSigninPage:), [link action]);
212 EXPECT_EQ(controller(), [link target]);
214 NSTextField* promo = base::mac::ObjCCast<NSTextField>(
215 [linksSubviews objectAtIndex:1]);
216 EXPECT_GT([[promo stringValue] length], 0U);
219 TEST_F(ProfileChooserControllerTest, RightClickTutorialShownAfterWelcome) {
220 switches::EnableNewAvatarMenuForTesting(
221 base::CommandLine::ForCurrentProcess());
222 // The welcome upgrade tutorial takes precedence so show it then dismiss it.
223 // The right click tutorial should be shown right away.
224 StartProfileChooserControllerWithTutorialMode(
225 profiles::TUTORIAL_MODE_WELCOME_UPGRADE);
227 [controller() dismissTutorial:nil];
228 AssertRightClickTutorialShown();
231 TEST_F(ProfileChooserControllerTest, RightClickTutorialShownAfterReopen) {
232 switches::EnableNewAvatarMenuForTesting(
233 base::CommandLine::ForCurrentProcess());
234 // The welcome upgrade tutorial takes precedence so show it then close the
235 // menu. Reopening the menu should show the tutorial.
236 StartProfileChooserController();
238 [controller() close];
239 StartProfileChooserController();
240 AssertRightClickTutorialShown();
242 // The tutorial must be manually dismissed so it should still be shown after
243 // closing and reopening the menu,
244 [controller() close];
245 StartProfileChooserController();
246 AssertRightClickTutorialShown();
249 TEST_F(ProfileChooserControllerTest, RightClickTutorialNotShownAfterDismiss) {
250 switches::EnableNewAvatarMenuForTesting(
251 base::CommandLine::ForCurrentProcess());
252 // The welcome upgrade tutorial takes precedence so show it then close the
253 // menu. Reopening the menu should show the tutorial.
254 StartProfileChooserController();
256 [controller() close];
257 StartProfileChooserControllerWithTutorialMode(
258 profiles::TUTORIAL_MODE_RIGHT_CLICK_SWITCHING);
259 AssertRightClickTutorialShown();
261 // Dismissing the tutorial should prevent it from being shown forever.
262 [controller() dismissTutorial:nil];
263 NSArray* subviews = [[[controller() window] contentView] subviews];
264 ASSERT_EQ(2U, [subviews count]);
265 subviews = [[subviews objectAtIndex:0] subviews];
267 // There should be 3 views since there's no tutorial
268 ASSERT_EQ(3U, [subviews count]);
270 // Closing and reopening the menu shouldn't show the tutorial.
271 [controller() close];
272 StartProfileChooserControllerWithTutorialMode(
273 profiles::TUTORIAL_MODE_RIGHT_CLICK_SWITCHING);
274 subviews = [[[controller() window] contentView] subviews];
275 ASSERT_EQ(2U, [subviews count]);
276 subviews = [[subviews objectAtIndex:0] subviews];
278 // There should be 3 views since there's no tutorial
279 ASSERT_EQ(3U, [subviews count]);
282 TEST_F(ProfileChooserControllerTest, OtherProfilesSortedAlphabetically) {
283 switches::EnableNewAvatarMenuForTesting(
284 base::CommandLine::ForCurrentProcess());
286 // Add two extra profiles, to make sure sorting is alphabetical and not
287 // by order of creation.
288 testing_profile_manager()->CreateTestingProfile(
289 "test3", scoped_ptr<syncable_prefs::PrefServiceSyncable>(),
290 base::ASCIIToUTF16("New Profile"), 1, std::string(),
291 TestingProfile::TestingFactories());
292 testing_profile_manager()->CreateTestingProfile(
293 "test4", scoped_ptr<syncable_prefs::PrefServiceSyncable>(),
294 base::ASCIIToUTF16("Another Test"), 1, std::string(),
295 TestingProfile::TestingFactories());
296 StartFastUserSwitcher();
298 NSArray* subviews = [[[controller() window] contentView] subviews];
299 ASSERT_EQ(2U, [subviews count]);
300 subviews = [[subviews objectAtIndex:0] subviews];
301 NSString* sortedNames[] = { @"Another Test",
305 // There are four "other" profiles, each with a button and a separator.
306 ASSERT_EQ([subviews count], 8U);
307 // There should be four "other profiles" items, sorted alphabetically. The
308 // "other profiles" start at index 2 (after the option buttons view and its
309 // separator), and each have a separator. We need to iterate through the
310 // profiles in the order displayed in the bubble, which is opposite from the
312 int sortedNameIndex = 0;
313 for (int i = 7; i > 0; i -= 2) {
314 // The item at index i is the separator.
315 NSButton* button = base::mac::ObjCCast<NSButton>(
316 [subviews objectAtIndex:i-1]);
318 [[button title] isEqualToString:sortedNames[sortedNameIndex++]]);
322 TEST_F(ProfileChooserControllerTest,
323 LocalProfileActiveCardLinksWithNewMenu) {
324 switches::EnableNewAvatarMenuForTesting(
325 base::CommandLine::ForCurrentProcess());
326 StartProfileChooserController();
327 NSArray* subviews = [[[controller() window] contentView] subviews];
328 ASSERT_EQ(2U, [subviews count]);
329 subviews = [[subviews objectAtIndex:0] subviews];
330 NSArray* activeCardSubviews = [[subviews objectAtIndex:2] subviews];
331 NSArray* activeCardLinks = [[activeCardSubviews objectAtIndex:0] subviews];
333 ASSERT_EQ(2U, [activeCardLinks count]);
335 // There should be a sign in button.
336 NSButton* link = base::mac::ObjCCast<NSButton>(
337 [activeCardLinks objectAtIndex:0]);
338 EXPECT_EQ(@selector(showInlineSigninPage:), [link action]);
339 EXPECT_EQ(controller(), [link target]);
341 // Local profiles have a signin promo.
342 NSTextField* promo = base::mac::ObjCCast<NSTextField>(
343 [activeCardLinks objectAtIndex:1]);
344 EXPECT_GT([[promo stringValue] length], 0U);
347 TEST_F(ProfileChooserControllerTest,
348 SignedInProfileActiveCardLinksWithAccountConsistency) {
349 switches::EnableAccountConsistencyForTesting(
350 base::CommandLine::ForCurrentProcess());
351 // Sign in the first profile.
352 ProfileInfoCache* cache = testing_profile_manager()->profile_info_cache();
353 cache->SetAuthInfoOfProfileAtIndex(0, kGaiaId, base::ASCIIToUTF16(kEmail));
355 StartProfileChooserController();
356 NSArray* subviews = [[[controller() window] contentView] subviews];
357 ASSERT_EQ(2U, [subviews count]);
358 subviews = [[subviews objectAtIndex:0] subviews];
359 NSArray* activeCardSubviews = [[subviews objectAtIndex:2] subviews];
360 NSArray* activeCardLinks = [[activeCardSubviews objectAtIndex:0] subviews];
362 // There is one link: manage accounts.
363 ASSERT_EQ(1U, [activeCardLinks count]);
364 NSButton* manageAccountsLink =
365 base::mac::ObjCCast<NSButton>([activeCardLinks objectAtIndex:0]);
366 EXPECT_EQ(@selector(showAccountManagement:), [manageAccountsLink action]);
367 EXPECT_EQ(controller(), [manageAccountsLink target]);
370 TEST_F(ProfileChooserControllerTest,
371 SignedInProfileActiveCardLinksWithNewMenu) {
372 switches::EnableNewAvatarMenuForTesting(
373 base::CommandLine::ForCurrentProcess());
374 // Sign in the first profile.
375 ProfileInfoCache* cache = testing_profile_manager()->profile_info_cache();
376 cache->SetAuthInfoOfProfileAtIndex(0, kGaiaId, base::ASCIIToUTF16(kEmail));
378 StartProfileChooserController();
379 NSArray* subviews = [[[controller() window] contentView] subviews];
380 ASSERT_EQ(2U, [subviews count]);
381 subviews = [[subviews objectAtIndex:0] subviews];
382 NSArray* activeCardSubviews = [[subviews objectAtIndex:2] subviews];
383 NSArray* activeCardLinks = [[activeCardSubviews objectAtIndex:0] subviews];
385 // There is one disabled button with the user's email.
386 ASSERT_EQ(1U, [activeCardLinks count]);
387 NSButton* emailButton =
388 base::mac::ObjCCast<NSButton>([activeCardLinks objectAtIndex:0]);
389 EXPECT_EQ(kEmail, base::SysNSStringToUTF8([emailButton title]));
390 EXPECT_EQ(nil, [emailButton action]);
391 EXPECT_FALSE([emailButton isEnabled]);
394 TEST_F(ProfileChooserControllerTest, AccountManagementLayout) {
395 switches::EnableAccountConsistencyForTesting(
396 base::CommandLine::ForCurrentProcess());
397 // Sign in the first profile.
398 ProfileInfoCache* cache = testing_profile_manager()->profile_info_cache();
399 cache->SetAuthInfoOfProfileAtIndex(0, kGaiaId, base::ASCIIToUTF16(kEmail));
401 // Mark that we are using the profile name on purpose, so that we don't
402 // fallback to testing the algorithm that chooses which default name
404 cache->SetProfileIsUsingDefaultNameAtIndex(0, false);
406 // Set up the AccountTrackerService, signin manager and the OAuth2Tokens.
407 Profile* profile = browser()->profile();
408 AccountTrackerServiceFactory::GetForProfile(profile)
409 ->SeedAccountInfo(kGaiaId, kEmail);
410 AccountTrackerServiceFactory::GetForProfile(profile)
411 ->SeedAccountInfo(kSecondaryGaiaId, kSecondaryEmail);
412 SigninManagerFactory::GetForProfile(profile)
413 ->SetAuthenticatedAccountInfo(kGaiaId, kEmail);
414 std::string account_id =
415 SigninManagerFactory::GetForProfile(profile)->GetAuthenticatedAccountId();
416 ProfileOAuth2TokenServiceFactory::GetForProfile(profile)
417 ->UpdateCredentials(account_id, kLoginToken);
418 account_id = AccountTrackerServiceFactory::GetForProfile(profile)
419 ->PickAccountIdForAccount(kSecondaryGaiaId, kSecondaryEmail);
420 ProfileOAuth2TokenServiceFactory::GetForProfile(profile)
421 ->UpdateCredentials(account_id, kLoginToken);
423 StartProfileChooserController();
424 [controller() initMenuContentsWithView:
425 profiles::BUBBLE_VIEW_MODE_ACCOUNT_MANAGEMENT];
427 NSArray* subviews = [[[controller() window] contentView] subviews];
428 ASSERT_EQ(2U, [subviews count]);
429 subviews = [[subviews objectAtIndex:0] subviews];
431 // There should be one active card, one accounts container, two separators
432 // and one option buttons view.
433 ASSERT_EQ(5U, [subviews count]);
435 // There should be three buttons and two separators in the option
437 NSArray* buttonSubviews = [[subviews objectAtIndex:0] subviews];
438 ASSERT_EQ(3U, [buttonSubviews count]);
440 // There should be a separator.
441 EXPECT_TRUE([[buttonSubviews objectAtIndex:1] isKindOfClass:[NSBox class]]);
443 // There should be an incognito button.
444 NSButton* incognitoButton =
445 base::mac::ObjCCast<NSButton>([buttonSubviews objectAtIndex:0]);
446 EXPECT_EQ(@selector(goIncognito:), [incognitoButton action]);
447 EXPECT_EQ(controller(), [incognitoButton target]);
449 // There should be a separator.
450 EXPECT_TRUE([[subviews objectAtIndex:3] isKindOfClass:[NSBox class]]);
452 // There should be a user switcher button.
453 NSButton* userSwitcherButton =
454 base::mac::ObjCCast<NSButton>([buttonSubviews objectAtIndex:2]);
455 EXPECT_EQ(@selector(showUserManager:), [userSwitcherButton action]);
456 EXPECT_EQ(controller(), [userSwitcherButton target]);
458 // In the accounts view, there should be the account list container
459 // accounts and one "add accounts" button.
460 NSArray* accountsSubviews = [[subviews objectAtIndex:2] subviews];
461 ASSERT_EQ(2U, [accountsSubviews count]);
463 NSButton* addAccountsButton =
464 base::mac::ObjCCast<NSButton>([accountsSubviews objectAtIndex:0]);
465 EXPECT_EQ(@selector(addAccount:), [addAccountsButton action]);
466 EXPECT_EQ(controller(), [addAccountsButton target]);
468 // There should be two accounts in the account list container.
469 NSArray* accountsListSubviews = [[accountsSubviews objectAtIndex:1] subviews];
470 ASSERT_EQ(2U, [accountsListSubviews count]);
472 NSButton* genericAccount =
473 base::mac::ObjCCast<NSButton>([accountsListSubviews objectAtIndex:0]);
474 NSButton* genericAccountDelete = base::mac::ObjCCast<NSButton>(
475 [[genericAccount subviews] objectAtIndex:0]);
476 EXPECT_EQ(@selector(showAccountRemovalView:), [genericAccountDelete action]);
477 EXPECT_EQ(controller(), [genericAccountDelete target]);
478 EXPECT_NE(-1, [genericAccountDelete tag]);
480 // Primary accounts are always last.
481 NSButton* primaryAccount =
482 base::mac::ObjCCast<NSButton>([accountsListSubviews objectAtIndex:1]);
483 NSButton* primaryAccountDelete = base::mac::ObjCCast<NSButton>(
484 [[primaryAccount subviews] objectAtIndex:0]);
485 EXPECT_EQ(@selector(showAccountRemovalView:), [primaryAccountDelete action]);
486 EXPECT_EQ(controller(), [primaryAccountDelete target]);
487 EXPECT_EQ(-1, [primaryAccountDelete tag]);
489 // There should be another separator.
490 EXPECT_TRUE([[subviews objectAtIndex:3] isKindOfClass:[NSBox class]]);
492 // There should be the profile avatar, name and a "hide accounts" link
493 // container in the active card view.
494 NSArray* activeCardSubviews = [[subviews objectAtIndex:4] subviews];
495 ASSERT_EQ(3U, [activeCardSubviews count]);
498 NSView* activeProfileImage = [activeCardSubviews objectAtIndex:2];
499 EXPECT_TRUE([activeProfileImage isKindOfClass:[NSButton class]]);
502 NSView* activeProfileName = [activeCardSubviews objectAtIndex:1];
503 EXPECT_TRUE([activeProfileName isKindOfClass:[NSButton class]]);
504 EXPECT_EQ(menu()->GetItemAt(0).name, base::SysNSStringToUTF16(
505 [base::mac::ObjCCast<NSButton>(activeProfileName) title]));
507 // Profile links. This is a local profile, so there should be a signin button.
508 NSArray* linksSubviews = [[activeCardSubviews objectAtIndex:0] subviews];
509 ASSERT_EQ(1U, [linksSubviews count]);
510 NSButton* link = base::mac::ObjCCast<NSButton>(
511 [linksSubviews objectAtIndex:0]);
512 EXPECT_EQ(@selector(hideAccountManagement:), [link action]);
513 EXPECT_EQ(controller(), [link target]);
516 TEST_F(ProfileChooserControllerTest, SignedInProfileLockDisabled) {
517 switches::EnableNewProfileManagementForTesting(
518 base::CommandLine::ForCurrentProcess());
519 // Sign in the first profile.
520 ProfileInfoCache* cache = testing_profile_manager()->profile_info_cache();
521 cache->SetAuthInfoOfProfileAtIndex(0, kGaiaId, base::ASCIIToUTF16(kEmail));
522 // The preference, not the email, determines whether the profile can lock.
523 browser()->profile()->GetPrefs()->SetString(
524 prefs::kGoogleServicesHostedDomain, "chromium.org");
526 StartProfileChooserController();
527 NSArray* subviews = [[[controller() window] contentView] subviews];
528 ASSERT_EQ(2U, [subviews count]);
529 subviews = [[subviews objectAtIndex:0] subviews];
531 // There will be two buttons and one separators in the option buttons view.
532 NSArray* buttonSubviews = [[subviews objectAtIndex:0] subviews];
533 ASSERT_EQ(3U, [buttonSubviews count]);
535 // The last button should not be the lock button.
536 NSButton* lastButton =
537 base::mac::ObjCCast<NSButton>([buttonSubviews objectAtIndex:0]);
538 ASSERT_TRUE(lastButton);
539 EXPECT_NE(@selector(lockProfile:), [lastButton action]);
542 TEST_F(ProfileChooserControllerTest, SignedInProfileLockEnabled) {
543 switches::EnableNewProfileManagementForTesting(
544 base::CommandLine::ForCurrentProcess());
545 // Sign in the first profile.
546 ProfileInfoCache* cache = testing_profile_manager()->profile_info_cache();
547 cache->SetAuthInfoOfProfileAtIndex(0, kGaiaId, base::ASCIIToUTF16(kEmail));
548 // The preference, not the email, determines whether the profile can lock.
549 browser()->profile()->GetPrefs()->SetString(
550 prefs::kGoogleServicesHostedDomain, "google.com");
551 // Lock is only available where a supervised user is present.
552 cache->SetSupervisedUserIdOfProfileAtIndex(1, kEmail);
554 StartProfileChooserController();
555 NSArray* subviews = [[[controller() window] contentView] subviews];
556 ASSERT_EQ(2U, [subviews count]);
557 subviews = [[subviews objectAtIndex:0] subviews];
559 // There will be three buttons and two separators in the option buttons view.
560 NSArray* buttonSubviews = [[subviews objectAtIndex:0] subviews];
561 ASSERT_EQ(5U, [buttonSubviews count]);
563 // There should be a lock button.
564 NSButton* lockButton =
565 base::mac::ObjCCast<NSButton>([buttonSubviews objectAtIndex:0]);
566 ASSERT_TRUE(lockButton);
567 EXPECT_EQ(@selector(lockProfile:), [lockButton action]);
568 EXPECT_EQ(controller(), [lockButton target]);
569 EXPECT_TRUE([lockButton isEnabled]);