Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / cocoa / profiles / profile_chooser_controller_unittest.mm
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.
4
5 #import "chrome/browser/ui/cocoa/profiles/profile_chooser_controller.h"
6
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_tracker_service_factory.h"
19 #include "chrome/browser/signin/fake_account_tracker_service.h"
20 #include "chrome/browser/signin/fake_profile_oauth2_token_service.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_header_helper.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/profile_oauth2_token_service.h"
30 #include "components/signin/core/browser/signin_manager.h"
31 #include "components/signin/core/common/profile_management_switches.h"
32
33 const std::string kEmail = "user@gmail.com";
34 const std::string kSecondaryEmail = "user2@gmail.com";
35 const std::string kLoginToken = "oauth2_login_token";
36
37 class ProfileChooserControllerTest : public CocoaProfileTest {
38  public:
39   ProfileChooserControllerTest() {
40   }
41
42   virtual void SetUp() override {
43     CocoaProfileTest::SetUp();
44     ASSERT_TRUE(browser()->profile());
45
46     AccountTrackerServiceFactory::GetInstance()->SetTestingFactory(
47         browser()->profile(), FakeAccountTrackerService::Build);
48     gcm::GCMProfileServiceFactory::GetInstance()->SetTestingFactory(
49         browser()->profile(), gcm::FakeGCMProfileService::Build);
50
51     TestingProfile::TestingFactories factories;
52     factories.push_back(
53         std::make_pair(ProfileOAuth2TokenServiceFactory::GetInstance(),
54                        BuildFakeProfileOAuth2TokenService));
55     factories.push_back(
56         std::make_pair(AccountTrackerServiceFactory::GetInstance(),
57                        FakeAccountTrackerService::Build));
58     testing_profile_manager()->
59         CreateTestingProfile("test1", scoped_ptr<PrefServiceSyncable>(),
60                              base::ASCIIToUTF16("Test 1"), 0, std::string(),
61                              factories);
62     testing_profile_manager()->
63         CreateTestingProfile("test2", scoped_ptr<PrefServiceSyncable>(),
64                              base::ASCIIToUTF16("Test 2"), 1, std::string(),
65                              TestingProfile::TestingFactories());
66
67     menu_ = new AvatarMenu(testing_profile_manager()->profile_info_cache(),
68                            NULL, NULL);
69     menu_->RebuildMenu();
70
71     // There should be the default profile + two profiles we created.
72     EXPECT_EQ(3U, menu_->GetNumberOfItems());
73   }
74
75   virtual void TearDown() override {
76     [controller() close];
77     controller_.reset();
78     CocoaProfileTest::TearDown();
79   }
80
81   void StartProfileChooserController() {
82     NSRect frame = [test_window() frame];
83     NSPoint point = NSMakePoint(NSMidX(frame), NSMidY(frame));
84     controller_.reset([[ProfileChooserController alloc]
85         initWithBrowser:browser()
86              anchoredAt:point
87                viewMode:profiles::BUBBLE_VIEW_MODE_PROFILE_CHOOSER
88            tutorialMode:profiles::TUTORIAL_MODE_NONE
89             serviceType:signin::GAIA_SERVICE_TYPE_NONE]);
90     [controller_ showWindow:nil];
91   }
92
93   void EnableFastUserSwitching() {
94     CommandLine::ForCurrentProcess()->AppendSwitch(
95         switches::kFastUserSwitching);
96   }
97
98   ProfileChooserController* controller() { return controller_; }
99   AvatarMenu* menu() { return menu_; }
100
101  private:
102   base::scoped_nsobject<ProfileChooserController> controller_;
103
104   // Weak; owned by |controller_|.
105   AvatarMenu* menu_;
106
107   DISALLOW_COPY_AND_ASSIGN(ProfileChooserControllerTest);
108 };
109
110 TEST_F(ProfileChooserControllerTest, InitialLayoutWithNewMenu) {
111   switches::EnableNewAvatarMenuForTesting(CommandLine::ForCurrentProcess());
112   StartProfileChooserController();
113
114   NSArray* subviews = [[[controller() window] contentView] subviews];
115   ASSERT_EQ(2U, [subviews count]);
116   subviews = [[subviews objectAtIndex:0] subviews];
117
118   // Three profiles means we should have one active card, one separator and
119   // one option buttons view. We also have an update promo for the new avatar
120   // menu.
121   // TODO(noms): Enforcing 4U fails on the waterfall debug bots, but it's not
122   // reproducible anywhere else.
123   ASSERT_GE([subviews count], 3U);
124
125   // There should be two buttons and a separator in the option buttons view.
126   NSArray* buttonSubviews = [[subviews objectAtIndex:0] subviews];
127   ASSERT_EQ(3U, [buttonSubviews count]);
128
129   // There should be an incognito button.
130   NSButton* incognitoButton =
131       base::mac::ObjCCast<NSButton>([buttonSubviews objectAtIndex:0]);
132   EXPECT_EQ(@selector(goIncognito:), [incognitoButton action]);
133   EXPECT_EQ(controller(), [incognitoButton target]);
134
135   // There should be a separator.
136   EXPECT_TRUE([[subviews objectAtIndex:1] isKindOfClass:[NSBox class]]);
137
138   // There should be a user switcher button.
139   NSButton* userSwitcherButton =
140       base::mac::ObjCCast<NSButton>([buttonSubviews objectAtIndex:2]);
141   EXPECT_EQ(@selector(showUserManager:), [userSwitcherButton action]);
142   EXPECT_EQ(controller(), [userSwitcherButton target]);
143
144   // There should be a separator.
145   EXPECT_TRUE([[subviews objectAtIndex:1] isKindOfClass:[NSBox class]]);
146
147   // There should be the profile avatar, name and links container in the active
148   // card view. The links displayed in the container are checked separately.
149   NSArray* activeCardSubviews = [[subviews objectAtIndex:2] subviews];
150   ASSERT_EQ(3U, [activeCardSubviews count]);
151
152   // Profile icon.
153   NSView* activeProfileImage = [activeCardSubviews objectAtIndex:2];
154   EXPECT_TRUE([activeProfileImage isKindOfClass:[NSButton class]]);
155
156   // Profile name.
157   NSView* activeProfileName = [activeCardSubviews objectAtIndex:1];
158   EXPECT_TRUE([activeProfileName isKindOfClass:[NSButton class]]);
159   EXPECT_EQ(menu()->GetItemAt(0).name, base::SysNSStringToUTF16(
160       [base::mac::ObjCCast<NSButton>(activeProfileName) title]));
161
162   // Profile links. This is a local profile, so there should be a signin button
163   // and a signin promo.
164   NSArray* linksSubviews = [[activeCardSubviews objectAtIndex:0] subviews];
165   ASSERT_EQ(2U, [linksSubviews count]);
166   NSButton* link = base::mac::ObjCCast<NSButton>(
167       [linksSubviews objectAtIndex:0]);
168   EXPECT_EQ(@selector(showInlineSigninPage:), [link action]);
169   EXPECT_EQ(controller(), [link target]);
170
171   NSTextField* promo = base::mac::ObjCCast<NSTextField>(
172       [linksSubviews objectAtIndex:1]);
173   EXPECT_GT([[promo stringValue] length], 0U);
174 }
175
176 TEST_F(ProfileChooserControllerTest, InitialLayoutWithFastUserSwitcher) {
177   switches::EnableNewAvatarMenuForTesting(CommandLine::ForCurrentProcess());
178   EnableFastUserSwitching();
179   StartProfileChooserController();
180
181   NSArray* subviews = [[[controller() window] contentView] subviews];
182   ASSERT_EQ(2U, [subviews count]);
183   subviews = [[subviews objectAtIndex:0] subviews];
184
185   // Three profiles means we should have one active card and a
186   // fast user switcher which has two "other" profiles and 2 separators, and
187   // an option buttons view with its separator. We also have a promo for
188   // the new avatar menu.
189   // TODO(noms): Enforcing 8U fails on the waterfall debug bots, but it's not
190   // reproducible anywhere else.
191   ASSERT_GE([subviews count], 7U);
192
193   // There should be two buttons and a separator in the option buttons view.
194   // These buttons are tested in InitialLayoutWithNewMenu.
195   NSArray* buttonSubviews = [[subviews objectAtIndex:0] subviews];
196   ASSERT_EQ(3U, [buttonSubviews count]);
197
198   // There should be a separator.
199   EXPECT_TRUE([[subviews objectAtIndex:1] isKindOfClass:[NSBox class]]);
200
201   // There should be two "other profiles" items. The items are drawn from the
202   // bottom up, so in the opposite order of those in the AvatarMenu.
203   int profileIndex = 1;
204   for (int i = 5; i >= 2; i -= 2) {
205     // Each profile button has a separator.
206     EXPECT_TRUE([[subviews objectAtIndex:i] isKindOfClass:[NSBox class]]);
207
208     NSButton* button = base::mac::ObjCCast<NSButton>(
209         [subviews objectAtIndex:i-1]);
210     EXPECT_EQ(menu()->GetItemAt(profileIndex).name,
211               base::SysNSStringToUTF16([button title]));
212     EXPECT_EQ(profileIndex, [button tag]);
213     EXPECT_EQ(@selector(switchToProfile:), [button action]);
214     EXPECT_EQ(controller(), [button target]);
215     profileIndex++;
216   }
217
218   // There should be the profile avatar, name and links container in the active
219   // card view. The links displayed in the container are checked separately.
220   NSArray* activeCardSubviews = [[subviews objectAtIndex:6] subviews];
221   ASSERT_EQ(3U, [activeCardSubviews count]);
222
223   // Profile icon.
224   NSView* activeProfileImage = [activeCardSubviews objectAtIndex:2];
225   EXPECT_TRUE([activeProfileImage isKindOfClass:[NSButton class]]);
226
227   // Profile name.
228   NSView* activeProfileName = [activeCardSubviews objectAtIndex:1];
229   EXPECT_TRUE([activeProfileName isKindOfClass:[NSButton class]]);
230   EXPECT_EQ(menu()->GetItemAt(0).name, base::SysNSStringToUTF16(
231       [base::mac::ObjCCast<NSButton>(activeProfileName) title]));
232
233   // Profile links. This is a local profile, so there should be a signin button
234   // and a signin promo. These are also tested in InitialLayoutWithNewMenu.
235   NSArray* linksSubviews = [[activeCardSubviews objectAtIndex:0] subviews];
236   EXPECT_EQ(2U, [linksSubviews count]);
237 }
238
239 TEST_F(ProfileChooserControllerTest, OtherProfilesSortedAlphabetically) {
240   switches::EnableNewAvatarMenuForTesting(CommandLine::ForCurrentProcess());
241   EnableFastUserSwitching();
242
243   // Add two extra profiles, to make sure sorting is alphabetical and not
244   // by order of creation.
245   testing_profile_manager()->
246       CreateTestingProfile("test3", scoped_ptr<PrefServiceSyncable>(),
247                            base::ASCIIToUTF16("New Profile"), 1, std::string(),
248                            TestingProfile::TestingFactories());
249   testing_profile_manager()->
250       CreateTestingProfile("test4", scoped_ptr<PrefServiceSyncable>(),
251                            base::ASCIIToUTF16("Another Test"), 1, std::string(),
252                            TestingProfile::TestingFactories());
253   StartProfileChooserController();
254
255   NSArray* subviews = [[[controller() window] contentView] subviews];
256   ASSERT_EQ(2U, [subviews count]);
257   subviews = [[subviews objectAtIndex:0] subviews];
258   NSString* sortedNames[] = { @"Another Test",
259                               @"New Profile",
260                               @"Test 1",
261                               @"Test 2" };
262   // There are four "other" profiles, each with a button and a separator, an
263   // active profile card, and an option buttons view with a separator. We
264   // also have an update promo for the new avatar menu.
265   // TODO(noms): Enforcing 12U fails on the waterfall debug bots, but it's not
266   // reproducible anywhere else.
267   ASSERT_GE([subviews count], 11U);
268   // There should be four "other profiles" items, sorted alphabetically. The
269   // "other profiles" start at index 2 (after the option buttons view and its
270   // separator), and each have a separator. We need to iterate through the
271   // profiles in the order displayed in the bubble, which is opposite from the
272   // drawn order.
273   int sortedNameIndex = 0;
274   for (int i = 9; i >= 2; i -= 2) {
275     // The item at index i is the separator.
276     NSButton* button = base::mac::ObjCCast<NSButton>(
277         [subviews objectAtIndex:i-1]);
278     EXPECT_TRUE(
279         [[button title] isEqualToString:sortedNames[sortedNameIndex++]]);
280   }
281 }
282
283 TEST_F(ProfileChooserControllerTest,
284     LocalProfileActiveCardLinksWithNewMenu) {
285   switches::EnableNewAvatarMenuForTesting(CommandLine::ForCurrentProcess());
286   StartProfileChooserController();
287   NSArray* subviews = [[[controller() window] contentView] subviews];
288   ASSERT_EQ(2U, [subviews count]);
289   subviews = [[subviews objectAtIndex:0] subviews];
290   NSArray* activeCardSubviews = [[subviews objectAtIndex:2] subviews];
291   NSArray* activeCardLinks = [[activeCardSubviews objectAtIndex:0] subviews];
292
293   ASSERT_EQ(2U, [activeCardLinks count]);
294
295   // There should be a sign in button.
296   NSButton* link = base::mac::ObjCCast<NSButton>(
297       [activeCardLinks objectAtIndex:0]);
298   EXPECT_EQ(@selector(showInlineSigninPage:), [link action]);
299   EXPECT_EQ(controller(), [link target]);
300
301   // Local profiles have a signin promo.
302   NSTextField* promo = base::mac::ObjCCast<NSTextField>(
303       [activeCardLinks objectAtIndex:1]);
304   EXPECT_GT([[promo stringValue] length], 0U);
305 }
306
307 TEST_F(ProfileChooserControllerTest,
308        SignedInProfileActiveCardLinksWithAccountConsistency) {
309   switches::EnableAccountConsistencyForTesting(
310       CommandLine::ForCurrentProcess());
311   // Sign in the first profile.
312   ProfileInfoCache* cache = testing_profile_manager()->profile_info_cache();
313   cache->SetUserNameOfProfileAtIndex(0, base::ASCIIToUTF16(kEmail));
314
315   StartProfileChooserController();
316   NSArray* subviews = [[[controller() window] contentView] subviews];
317   ASSERT_EQ(2U, [subviews count]);
318   subviews = [[subviews objectAtIndex:0] subviews];
319   NSArray* activeCardSubviews = [[subviews objectAtIndex:2] subviews];
320   NSArray* activeCardLinks = [[activeCardSubviews objectAtIndex:0] subviews];
321
322   // There is one link: manage accounts.
323   ASSERT_EQ(1U, [activeCardLinks count]);
324   NSButton* manageAccountsLink =
325       base::mac::ObjCCast<NSButton>([activeCardLinks objectAtIndex:0]);
326   EXPECT_EQ(@selector(showAccountManagement:), [manageAccountsLink action]);
327   EXPECT_EQ(controller(), [manageAccountsLink target]);
328 }
329
330 TEST_F(ProfileChooserControllerTest,
331     SignedInProfileActiveCardLinksWithNewMenu) {
332   switches::EnableNewAvatarMenuForTesting(CommandLine::ForCurrentProcess());
333   // Sign in the first profile.
334   ProfileInfoCache* cache = testing_profile_manager()->profile_info_cache();
335   cache->SetUserNameOfProfileAtIndex(0, base::ASCIIToUTF16(kEmail));
336
337   StartProfileChooserController();
338   NSArray* subviews = [[[controller() window] contentView] subviews];
339   ASSERT_EQ(2U, [subviews count]);
340   subviews = [[subviews objectAtIndex:0] subviews];
341   NSArray* activeCardSubviews = [[subviews objectAtIndex:2] subviews];
342   NSArray* activeCardLinks = [[activeCardSubviews objectAtIndex:0] subviews];
343
344   // There is one disabled button with the user's email.
345   ASSERT_EQ(1U, [activeCardLinks count]);
346   NSButton* emailButton =
347       base::mac::ObjCCast<NSButton>([activeCardLinks objectAtIndex:0]);
348   EXPECT_EQ(kEmail, base::SysNSStringToUTF8([emailButton title]));
349   EXPECT_EQ(nil, [emailButton action]);
350   EXPECT_FALSE([emailButton isEnabled]);
351 }
352
353 TEST_F(ProfileChooserControllerTest, AccountManagementLayout) {
354   switches::EnableAccountConsistencyForTesting(
355       CommandLine::ForCurrentProcess());
356   // Sign in the first profile.
357   ProfileInfoCache* cache = testing_profile_manager()->profile_info_cache();
358   cache->SetUserNameOfProfileAtIndex(0, base::ASCIIToUTF16(kEmail));
359
360   // Mark that we are using the profile name on purpose, so that we don't
361   // fallback to testing the algorithm that chooses which default name
362   // should be used.
363   cache->SetProfileIsUsingDefaultNameAtIndex(0, false);
364
365   // Set up the signin manager and the OAuth2Tokens.
366   Profile* profile = browser()->profile();
367   SigninManagerFactory::GetForProfile(profile)->
368       SetAuthenticatedUsername(kEmail);
369   ProfileOAuth2TokenServiceFactory::GetForProfile(profile)->
370       UpdateCredentials(kEmail, kLoginToken);
371   ProfileOAuth2TokenServiceFactory::GetForProfile(profile)->
372       UpdateCredentials(kSecondaryEmail, kLoginToken);
373
374   StartProfileChooserController();
375   [controller() initMenuContentsWithView:
376       profiles::BUBBLE_VIEW_MODE_ACCOUNT_MANAGEMENT];
377
378   NSArray* subviews = [[[controller() window] contentView] subviews];
379   ASSERT_EQ(2U, [subviews count]);
380   subviews = [[subviews objectAtIndex:0] subviews];
381
382   // There should be one active card, one accounts container, two separators
383   // and one option buttons view.
384   ASSERT_EQ(5U, [subviews count]);
385
386   // There should be three buttons and two separators in the option
387   // buttons view.
388   NSArray* buttonSubviews = [[subviews objectAtIndex:0] subviews];
389   ASSERT_EQ(3U, [buttonSubviews count]);
390
391   // There should be a separator.
392   EXPECT_TRUE([[buttonSubviews objectAtIndex:1] isKindOfClass:[NSBox class]]);
393
394   // There should be an incognito button.
395   NSButton* incognitoButton =
396       base::mac::ObjCCast<NSButton>([buttonSubviews objectAtIndex:0]);
397   EXPECT_EQ(@selector(goIncognito:), [incognitoButton action]);
398   EXPECT_EQ(controller(), [incognitoButton target]);
399
400   // There should be a separator.
401   EXPECT_TRUE([[subviews objectAtIndex:3] isKindOfClass:[NSBox class]]);
402
403   // There should be a user switcher button.
404   NSButton* userSwitcherButton =
405       base::mac::ObjCCast<NSButton>([buttonSubviews objectAtIndex:2]);
406   EXPECT_EQ(@selector(showUserManager:), [userSwitcherButton action]);
407   EXPECT_EQ(controller(), [userSwitcherButton target]);
408
409   // In the accounts view, there should be the account list container
410   // accounts and one "add accounts" button.
411   NSArray* accountsSubviews = [[subviews objectAtIndex:2] subviews];
412   ASSERT_EQ(2U, [accountsSubviews count]);
413
414   NSButton* addAccountsButton =
415       base::mac::ObjCCast<NSButton>([accountsSubviews objectAtIndex:0]);
416   EXPECT_EQ(@selector(addAccount:), [addAccountsButton action]);
417   EXPECT_EQ(controller(), [addAccountsButton target]);
418
419   // There should be two accounts in the account list container.
420   NSArray* accountsListSubviews = [[accountsSubviews objectAtIndex:1] subviews];
421   ASSERT_EQ(2U, [accountsListSubviews count]);
422
423   NSButton* genericAccount =
424       base::mac::ObjCCast<NSButton>([accountsListSubviews objectAtIndex:0]);
425   NSButton* genericAccountDelete = base::mac::ObjCCast<NSButton>(
426   [[genericAccount subviews] objectAtIndex:0]);
427   EXPECT_EQ(@selector(showAccountRemovalView:), [genericAccountDelete action]);
428   EXPECT_EQ(controller(), [genericAccountDelete target]);
429   EXPECT_NE(-1, [genericAccountDelete tag]);
430
431   // Primary accounts are always last.
432   NSButton* primaryAccount =
433       base::mac::ObjCCast<NSButton>([accountsListSubviews objectAtIndex:1]);
434   NSButton* primaryAccountDelete = base::mac::ObjCCast<NSButton>(
435       [[primaryAccount subviews] objectAtIndex:0]);
436   EXPECT_EQ(@selector(showAccountRemovalView:), [primaryAccountDelete action]);
437   EXPECT_EQ(controller(), [primaryAccountDelete target]);
438   EXPECT_EQ(-1, [primaryAccountDelete tag]);
439
440   // There should be another separator.
441   EXPECT_TRUE([[subviews objectAtIndex:3] isKindOfClass:[NSBox class]]);
442
443   // There should be the profile avatar, name and a "hide accounts" link
444   // container in the active card view.
445   NSArray* activeCardSubviews = [[subviews objectAtIndex:4] subviews];
446   ASSERT_EQ(3U, [activeCardSubviews count]);
447
448   // Profile icon.
449   NSView* activeProfileImage = [activeCardSubviews objectAtIndex:2];
450   EXPECT_TRUE([activeProfileImage isKindOfClass:[NSButton class]]);
451
452   // Profile name.
453   NSView* activeProfileName = [activeCardSubviews objectAtIndex:1];
454   EXPECT_TRUE([activeProfileName isKindOfClass:[NSButton class]]);
455   EXPECT_EQ(menu()->GetItemAt(0).name, base::SysNSStringToUTF16(
456       [base::mac::ObjCCast<NSButton>(activeProfileName) title]));
457
458   // Profile links. This is a local profile, so there should be a signin button.
459   NSArray* linksSubviews = [[activeCardSubviews objectAtIndex:0] subviews];
460   ASSERT_EQ(1U, [linksSubviews count]);
461   NSButton* link = base::mac::ObjCCast<NSButton>(
462       [linksSubviews objectAtIndex:0]);
463   EXPECT_EQ(@selector(hideAccountManagement:), [link action]);
464   EXPECT_EQ(controller(), [link target]);
465 }
466
467 TEST_F(ProfileChooserControllerTest, SignedInProfileLockDisabled) {
468   switches::EnableNewProfileManagementForTesting(
469       CommandLine::ForCurrentProcess());
470   // Sign in the first profile.
471   ProfileInfoCache* cache = testing_profile_manager()->profile_info_cache();
472   cache->SetUserNameOfProfileAtIndex(0, base::ASCIIToUTF16(kEmail));
473   // The preference, not the email, determines whether the profile can lock.
474   browser()->profile()->GetPrefs()->SetString(
475       prefs::kGoogleServicesHostedDomain, "chromium.org");
476
477   StartProfileChooserController();
478   NSArray* subviews = [[[controller() window] contentView] subviews];
479   ASSERT_EQ(2U, [subviews count]);
480   subviews = [[subviews objectAtIndex:0] subviews];
481
482   // There will be two buttons and one separators in the option buttons view.
483   NSArray* buttonSubviews = [[subviews objectAtIndex:0] subviews];
484   ASSERT_EQ(3U, [buttonSubviews count]);
485
486   // The last button should not be the lock button.
487   NSButton* lastButton =
488       base::mac::ObjCCast<NSButton>([buttonSubviews objectAtIndex:0]);
489   ASSERT_TRUE(lastButton);
490   EXPECT_NE(@selector(lockProfile:), [lastButton action]);
491 }
492
493 TEST_F(ProfileChooserControllerTest, SignedInProfileLockEnabled) {
494   switches::EnableNewProfileManagementForTesting(
495       CommandLine::ForCurrentProcess());
496   // Sign in the first profile.
497   ProfileInfoCache* cache = testing_profile_manager()->profile_info_cache();
498   cache->SetUserNameOfProfileAtIndex(0, base::ASCIIToUTF16(kEmail));
499   // The preference, not the email, determines whether the profile can lock.
500   browser()->profile()->GetPrefs()->SetString(
501       prefs::kGoogleServicesHostedDomain, "google.com");
502   // Lock is only available where a supervised user is present.
503   cache->SetSupervisedUserIdOfProfileAtIndex(1, kEmail);
504
505   StartProfileChooserController();
506   NSArray* subviews = [[[controller() window] contentView] subviews];
507   ASSERT_EQ(2U, [subviews count]);
508   subviews = [[subviews objectAtIndex:0] subviews];
509
510   // There will be three buttons and two separators in the option buttons view.
511   NSArray* buttonSubviews = [[subviews objectAtIndex:0] subviews];
512   ASSERT_EQ(5U, [buttonSubviews count]);
513
514   // There should be a lock button.
515   NSButton* lockButton =
516       base::mac::ObjCCast<NSButton>([buttonSubviews objectAtIndex:0]);
517   ASSERT_TRUE(lockButton);
518   EXPECT_EQ(@selector(lockProfile:), [lockButton action]);
519   EXPECT_EQ(controller(), [lockButton target]);
520   EXPECT_TRUE([lockButton isEnabled]);
521 }