Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / ui / cocoa / profiles / profile_chooser_controller_unittest.mm
blob5d130365a4941c78ce9a324deee789444f86899e
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 {
42  public:
43   ProfileChooserControllerTest() {
44     TestingProfile::TestingFactories factories;
45     factories.push_back(
46         std::make_pair(ProfileOAuth2TokenServiceFactory::GetInstance(),
47                        BuildFakeProfileOAuth2TokenService));
48     factories.push_back(
49         std::make_pair(AccountFetcherServiceFactory::GetInstance(),
50                        FakeAccountFetcherServiceBuilder::BuildForTests));
51     AddTestingFactories(factories);
52   }
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(),
71                            NULL, NULL);
72     menu_->RebuildMenu();
74     // There should be the default profile + two profiles we created.
75     EXPECT_EQ(3U, menu_->GetNumberOfItems());
76   }
78   void TearDown() override {
79     [controller() close];
80     controller_.reset();
81     CocoaProfileTest::TearDown();
82   }
84   void StartProfileChooserController() {
85     StartProfileChooserControllerWithTutorialMode(profiles::TUTORIAL_MODE_NONE);
86   }
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()
94              anchoredAt:point
95                viewMode:profiles::BUBBLE_VIEW_MODE_PROFILE_CHOOSER
96            tutorialMode:mode
97             serviceType:signin::GAIA_SERVICE_TYPE_NONE]);
98     [controller_ showWindow:nil];
99   }
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);
126   }
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()
133              anchoredAt:point
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];
138   }
140   ProfileChooserController* controller() { return controller_; }
141   AvatarMenu* menu() { return menu_; }
143  private:
144   base::scoped_nsobject<ProfileChooserController> controller_;
146   // Weak; owned by |controller_|.
147   AvatarMenu* menu_;
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
163   // menu.
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]);
195   // Profile icon.
196   NSView* activeProfileImage = [activeCardSubviews objectAtIndex:2];
197   EXPECT_TRUE([activeProfileImage isKindOfClass:[NSButton class]]);
199   // Profile name.
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",
302                               @"New Profile",
303                               @"Test 1",
304                               @"Test 2" };
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
311   // drawn order.
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]);
317     EXPECT_TRUE(
318         [[button title] isEqualToString:sortedNames[sortedNameIndex++]]);
319   }
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
403   // should be used.
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
436   // buttons view.
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]);
497   // Profile icon.
498   NSView* activeProfileImage = [activeCardSubviews objectAtIndex:2];
499   EXPECT_TRUE([activeProfileImage isKindOfClass:[NSButton class]]);
501   // Profile name.
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]);