Upstream version 7.36.149.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 #include "base/mac/scoped_nsobject.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/strings/sys_string_conversions.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "chrome/browser/prefs/pref_service_syncable.h"
13 #include "chrome/browser/profiles/avatar_menu.h"
14 #include "chrome/browser/profiles/profile_info_cache.h"
15 #include "chrome/browser/signin/fake_profile_oauth2_token_service.h"
16 #include "chrome/browser/signin/fake_profile_oauth2_token_service_builder.h"
17 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
18 #include "chrome/browser/signin/signin_manager_factory.h"
19 #include "chrome/browser/ui/browser.h"
20 #include "chrome/browser/ui/cocoa/cocoa_profile_test.h"
21 #include "chrome/common/chrome_switches.h"
22 #include "components/signin/core/browser/profile_oauth2_token_service.h"
23 #include "components/signin/core/browser/signin_manager.h"
24
25 const std::string kEmail = "user@gmail.com";
26 const std::string kSecondaryEmail = "user2@gmail.com";
27 const std::string kLoginToken = "oauth2_login_token";
28
29 class ProfileChooserControllerTest : public CocoaProfileTest {
30  public:
31   ProfileChooserControllerTest() {
32   }
33
34   virtual void SetUp() OVERRIDE {
35     CocoaProfileTest::SetUp();
36     ASSERT_TRUE(browser()->profile());
37
38     TestingProfile::TestingFactories factories;
39     factories.push_back(
40         std::make_pair(ProfileOAuth2TokenServiceFactory::GetInstance(),
41                        BuildFakeProfileOAuth2TokenService));
42     testing_profile_manager()->
43         CreateTestingProfile("test1", scoped_ptr<PrefServiceSyncable>(),
44                              base::ASCIIToUTF16("Test 1"), 0, std::string(),
45                              factories);
46     testing_profile_manager()->
47         CreateTestingProfile("test2", scoped_ptr<PrefServiceSyncable>(),
48                              base::ASCIIToUTF16("Test 2"), 1, std::string(),
49                              TestingProfile::TestingFactories());
50
51     menu_ = new AvatarMenu(testing_profile_manager()->profile_info_cache(),
52                            NULL, NULL);
53     menu_->RebuildMenu();
54
55     // There should be the default profile + two profiles we created.
56     EXPECT_EQ(3U, menu_->GetNumberOfItems());
57   }
58
59   virtual void TearDown() OVERRIDE {
60     [controller() close];
61     controller_.reset();
62     CocoaProfileTest::TearDown();
63   }
64
65   void StartProfileChooserController() {
66     NSRect frame = [test_window() frame];
67     NSPoint point = NSMakePoint(NSMidX(frame), NSMidY(frame));
68     controller_.reset([[ProfileChooserController alloc]
69         initWithBrowser:browser()
70              anchoredAt:point
71                withMode:BUBBLE_VIEW_MODE_PROFILE_CHOOSER]);
72     [controller_ showWindow:nil];
73   }
74
75   void EnableNewProfileManagement() {
76     CommandLine::ForCurrentProcess()->AppendSwitch(
77         switches::kNewProfileManagement);
78   }
79
80   void EnableNewAvatarMenuOnly() {
81     CommandLine::ForCurrentProcess()->AppendSwitch(switches::kNewAvatarMenu);
82   }
83
84   void EnableFastUserSwitching() {
85     CommandLine::ForCurrentProcess()->AppendSwitch(
86         switches::kFastUserSwitching);
87   }
88
89   ProfileChooserController* controller() { return controller_; }
90   AvatarMenu* menu() { return menu_; }
91
92  private:
93   base::scoped_nsobject<ProfileChooserController> controller_;
94
95   // Weak; owned by |controller_|.
96   AvatarMenu* menu_;
97
98   DISALLOW_COPY_AND_ASSIGN(ProfileChooserControllerTest);
99 };
100
101 TEST_F(ProfileChooserControllerTest, InitialLayoutWithNewManagement) {
102   EnableNewProfileManagement();
103   StartProfileChooserController();
104
105   NSArray* subviews = [[[controller() window] contentView] subviews];
106   EXPECT_EQ(1U, [subviews count]);
107   subviews = [[subviews objectAtIndex:0] subviews];
108
109   // Three profiles means we should have one active card, one separator and
110   // one option buttons view.
111   EXPECT_EQ(3U, [subviews count]);
112
113   // For a local profile, there should be one button in the option buttons view.
114   NSArray* buttonSubviews = [[subviews objectAtIndex:0] subviews];
115   EXPECT_EQ(1U, [buttonSubviews count]);
116   NSButton* button = static_cast<NSButton*>([buttonSubviews objectAtIndex:0]);
117   EXPECT_EQ(@selector(showUserManager:), [button action]);
118   EXPECT_EQ(controller(), [button target]);
119
120   // There should be a separator.
121   EXPECT_TRUE([[subviews objectAtIndex:1] isKindOfClass:[NSBox class]]);
122
123   // There should be the profile avatar, name and links container in the active
124   // card view. The links displayed in the container are checked separately.
125   NSArray* activeCardSubviews = [[subviews objectAtIndex:2] subviews];
126   EXPECT_EQ(3U, [activeCardSubviews count]);
127
128   // Profile icon.
129   NSView* activeProfileImage = [activeCardSubviews objectAtIndex:2];
130   EXPECT_TRUE([activeProfileImage isKindOfClass:[NSImageView class]]);
131
132   // Profile name.
133   NSView* activeProfileName = [activeCardSubviews objectAtIndex:1];
134   EXPECT_TRUE([activeProfileName isKindOfClass:[NSButton class]]);
135   EXPECT_EQ(menu()->GetItemAt(0).name, base::SysNSStringToUTF16(
136       [static_cast<NSButton*>(activeProfileName) title]));
137
138   // Profile links. This is a local profile, so there should be a signin button.
139   NSArray* linksSubviews = [[activeCardSubviews objectAtIndex:0] subviews];
140   EXPECT_EQ(1U, [linksSubviews count]);
141   NSButton* link = static_cast<NSButton*>([linksSubviews objectAtIndex:0]);
142   EXPECT_EQ(@selector(showInlineSigninPage:), [link action]);
143   EXPECT_EQ(controller(), [link target]);
144 }
145
146 TEST_F(ProfileChooserControllerTest, InitialLayoutWithNewMenu) {
147   EnableNewAvatarMenuOnly();
148   StartProfileChooserController();
149
150   NSArray* subviews = [[[controller() window] contentView] subviews];
151   EXPECT_EQ(1U, [subviews count]);
152   subviews = [[subviews objectAtIndex:0] subviews];
153
154   // Three profiles means we should have one active card and a
155   // fast user switcher which has two "other" profiles and 2 separators. In
156   // this flow we also have the tutorial view.
157   EXPECT_EQ(6U, [subviews count]);
158
159   // There should be two "other profiles" items. The items are drawn from the
160   // bottom up, so in the opposite order of those in the AvatarMenu.
161   int profileIndex = 1;
162   for (int i = 3; i >= 0; i -= 2) {
163     // Each profile button has a separator.
164     EXPECT_TRUE([[subviews objectAtIndex:i] isKindOfClass:[NSBox class]]);
165
166     NSButton* button = static_cast<NSButton*>([subviews objectAtIndex:i-1]);
167     EXPECT_EQ(menu()->GetItemAt(profileIndex).name,
168               base::SysNSStringToUTF16([button title]));
169     EXPECT_EQ(profileIndex, [button tag]);
170     EXPECT_EQ(@selector(switchToProfile:), [button action]);
171     EXPECT_EQ(controller(), [button target]);
172     profileIndex++;
173   }
174
175   // There should be the profile avatar, name and links container in the active
176   // card view. The links displayed in the container are checked separately.
177   NSArray* activeCardSubviews = [[subviews objectAtIndex:4] subviews];
178   EXPECT_EQ(3U, [activeCardSubviews count]);
179
180   // Profile icon.
181   NSView* activeProfileImage = [activeCardSubviews objectAtIndex:2];
182   EXPECT_TRUE([activeProfileImage isKindOfClass:[NSImageView class]]);
183
184   // Profile name.
185   NSView* activeProfileName = [activeCardSubviews objectAtIndex:1];
186   EXPECT_TRUE([activeProfileName isKindOfClass:[NSButton class]]);
187   EXPECT_EQ(menu()->GetItemAt(0).name, base::SysNSStringToUTF16(
188       [static_cast<NSButton*>(activeProfileName) title]));
189
190   // Profile links. This is a local profile, so there should be a signin button.
191   NSArray* linksSubviews = [[activeCardSubviews objectAtIndex:0] subviews];
192   EXPECT_EQ(1U, [linksSubviews count]);
193   NSButton* link = static_cast<NSButton*>([linksSubviews objectAtIndex:0]);
194   EXPECT_EQ(@selector(showTabbedSigninPage:), [link action]);
195   EXPECT_EQ(controller(), [link target]);
196
197   // There is a tutorial view card at the top.
198   EXPECT_TRUE([[subviews objectAtIndex:5] isKindOfClass:[NSView class]]);
199 }
200
201 TEST_F(ProfileChooserControllerTest, InitialLayoutWithFastUserSwitcher) {
202   EnableNewProfileManagement();
203   EnableFastUserSwitching();
204   StartProfileChooserController();
205
206   NSArray* subviews = [[[controller() window] contentView] subviews];
207   EXPECT_EQ(1U, [subviews count]);
208   subviews = [[subviews objectAtIndex:0] subviews];
209
210   // Three profiles means we should have one active card, two "other" profiles,
211   // each with a separator, and one option buttons view.
212   EXPECT_EQ(7U, [subviews count]);
213
214   // For a local profile, there should be one button in the option buttons view.
215   NSArray* buttonSubviews = [[subviews objectAtIndex:0] subviews];
216   EXPECT_EQ(1U, [buttonSubviews count]);
217   NSButton* button = static_cast<NSButton*>([buttonSubviews objectAtIndex:0]);
218   EXPECT_EQ(@selector(showUserManager:), [button action]);
219   EXPECT_EQ(controller(), [button target]);
220
221   // There should be a separator.
222   EXPECT_TRUE([[subviews objectAtIndex:1] isKindOfClass:[NSBox class]]);
223
224   // There should be two "other profiles" items. The items are drawn from the
225   // bottom up, so in the opposite order of those in the AvatarMenu.
226   int profileIndex = 1;
227   for (int i = 5; i >= 2; i -= 2) {
228     // Each profile button has a separator.
229     EXPECT_TRUE([[subviews objectAtIndex:i] isKindOfClass:[NSBox class]]);
230
231     NSButton* button = static_cast<NSButton*>([subviews objectAtIndex:i-1]);
232     EXPECT_EQ(menu()->GetItemAt(profileIndex).name,
233               base::SysNSStringToUTF16([button title]));
234     EXPECT_EQ(profileIndex, [button tag]);
235     EXPECT_EQ(@selector(switchToProfile:), [button action]);
236     EXPECT_EQ(controller(), [button target]);
237     profileIndex++;
238   }
239
240   // There should be the profile avatar, name and links container in the active
241   // card view. These have been checked separately.
242   NSArray* activeCardSubviews = [[subviews objectAtIndex:6] subviews];
243   EXPECT_EQ(3U, [activeCardSubviews count]);
244 }
245
246 TEST_F(ProfileChooserControllerTest, OtherProfilesSortedAlphabetically) {
247   EnableNewAvatarMenuOnly();
248
249   // Add two extra profiles, to make sure sorting is alphabetical and not
250   // by order of creation.
251   testing_profile_manager()->
252       CreateTestingProfile("test3", scoped_ptr<PrefServiceSyncable>(),
253                            base::ASCIIToUTF16("New Profile"), 1, std::string(),
254                            TestingProfile::TestingFactories());
255   testing_profile_manager()->
256       CreateTestingProfile("test4", scoped_ptr<PrefServiceSyncable>(),
257                            base::ASCIIToUTF16("Another Test"), 1, std::string(),
258                            TestingProfile::TestingFactories());
259   StartProfileChooserController();
260
261   NSArray* subviews = [[[controller() window] contentView] subviews];
262   EXPECT_EQ(1U, [subviews count]);
263   subviews = [[subviews objectAtIndex:0] subviews];
264   NSString* sortedNames[] = { @"Another Test",
265                               @"New Profile",
266                               @"Test 1",
267                               @"Test 2" };
268   // There are four "other" profiles, each with a button and a separator, an
269   // active profile card, and a tutorial card.
270   EXPECT_EQ(10U, [subviews count]);
271   // There should be four "other profiles" items, sorted alphabetically.
272   // The "other profiles" start at index 0, and each have a separator. We
273   // need to iterate through the profiles in the order displayed in the bubble,
274   // which is opposite from the drawn order.
275   int sortedNameIndex = 0;
276   for (int i = 7; i >= 0; i -= 2) {
277     // The item at index i is the separator.
278     NSButton* button = static_cast<NSButton*>([subviews objectAtIndex:i-1]);
279     EXPECT_TRUE(
280         [[button title] isEqualToString:sortedNames[sortedNameIndex++]]);
281   }
282 }
283
284 TEST_F(ProfileChooserControllerTest,
285     LocalProfileActiveCardLinksWithNewManagement) {
286   EnableNewProfileManagement();
287   StartProfileChooserController();
288   NSArray* subviews = [[[controller() window] contentView] subviews];
289   EXPECT_EQ(1U, [subviews count]);
290   subviews = [[subviews objectAtIndex:0] subviews];
291   NSArray* activeCardSubviews = [[subviews objectAtIndex:2] subviews];
292   NSArray* activeCardLinks = [[activeCardSubviews objectAtIndex:0] subviews];
293
294   // There should be one "sign in" link.
295   EXPECT_EQ(1U, [activeCardLinks count]);
296   NSButton* signinLink =
297       static_cast<NSButton*>([activeCardLinks objectAtIndex:0]);
298   EXPECT_EQ(@selector(showInlineSigninPage:), [signinLink action]);
299   EXPECT_EQ(controller(), [signinLink target]);
300 }
301
302 TEST_F(ProfileChooserControllerTest,
303     LocalProfileActiveCardLinksWithNewMenu) {
304   EnableNewAvatarMenuOnly();
305   StartProfileChooserController();
306   NSArray* subviews = [[[controller() window] contentView] subviews];
307   EXPECT_EQ(1U, [subviews count]);
308   subviews = [[subviews objectAtIndex:0] subviews];
309   NSArray* activeCardSubviews = [[subviews objectAtIndex:4] subviews];
310   NSArray* activeCardLinks = [[activeCardSubviews objectAtIndex:0] subviews];
311
312   // There should be one "sign in" link.
313   EXPECT_EQ(1U, [activeCardLinks count]);
314   NSButton* signinLink =
315       static_cast<NSButton*>([activeCardLinks objectAtIndex:0]);
316   EXPECT_EQ(@selector(showTabbedSigninPage:), [signinLink action]);
317   EXPECT_EQ(controller(), [signinLink target]);
318 }
319
320 TEST_F(ProfileChooserControllerTest,
321     SignedInProfileActiveCardLinksWithNewManagement) {
322   EnableNewProfileManagement();
323   // Sign in the first profile.
324   ProfileInfoCache* cache = testing_profile_manager()->profile_info_cache();
325   cache->SetUserNameOfProfileAtIndex(0, base::ASCIIToUTF16(kEmail));
326
327   StartProfileChooserController();
328   NSArray* subviews = [[[controller() window] contentView] subviews];
329   EXPECT_EQ(1U, [subviews count]);
330   subviews = [[subviews objectAtIndex:0] subviews];
331   NSArray* activeCardSubviews = [[subviews objectAtIndex:2] subviews];
332   NSArray* activeCardLinks = [[activeCardSubviews objectAtIndex:0] subviews];
333
334   // There is one link: manage accounts.
335   EXPECT_EQ(1U, [activeCardLinks count]);
336   NSButton* manageAccountsLink =
337       static_cast<NSButton*>([activeCardLinks objectAtIndex:0]);
338   EXPECT_EQ(@selector(showAccountManagement:), [manageAccountsLink action]);
339   EXPECT_EQ(controller(), [manageAccountsLink target]);
340 }
341
342 TEST_F(ProfileChooserControllerTest,
343     SignedInProfileActiveCardLinksWithNewMenu) {
344   EnableNewAvatarMenuOnly();
345   // Sign in the first profile.
346   ProfileInfoCache* cache = testing_profile_manager()->profile_info_cache();
347   cache->SetUserNameOfProfileAtIndex(0, base::ASCIIToUTF16(kEmail));
348
349   StartProfileChooserController();
350   NSArray* subviews = [[[controller() window] contentView] subviews];
351   EXPECT_EQ(1U, [subviews count]);
352   subviews = [[subviews objectAtIndex:0] subviews];
353   NSArray* activeCardSubviews = [[subviews objectAtIndex:4] subviews];
354   NSArray* activeCardLinks = [[activeCardSubviews objectAtIndex:0] subviews];
355
356   // There is one link, without a target and with the user's email.
357   EXPECT_EQ(1U, [activeCardLinks count]);
358   NSButton* emailLink =
359       static_cast<NSButton*>([activeCardLinks objectAtIndex:0]);
360   EXPECT_EQ(nil, [emailLink action]);
361   EXPECT_EQ(kEmail, base::SysNSStringToUTF8([emailLink title]));
362   EXPECT_EQ(controller(), [emailLink target]);
363 }
364
365 TEST_F(ProfileChooserControllerTest, AccountManagementLayout) {
366   EnableNewProfileManagement();
367   // Sign in the first profile.
368   ProfileInfoCache* cache = testing_profile_manager()->profile_info_cache();
369   cache->SetUserNameOfProfileAtIndex(0, base::ASCIIToUTF16(kEmail));
370
371   // Set up the signin manager and the OAuth2Tokens.
372   Profile* profile = browser()->profile();
373   SigninManagerFactory::GetForProfile(profile)->
374       SetAuthenticatedUsername(kEmail);
375   ProfileOAuth2TokenServiceFactory::GetForProfile(profile)->
376       UpdateCredentials(kEmail, kLoginToken);
377   ProfileOAuth2TokenServiceFactory::GetForProfile(profile)->
378       UpdateCredentials(kSecondaryEmail, kLoginToken);
379
380   StartProfileChooserController();
381   [controller() initMenuContentsWithView:BUBBLE_VIEW_MODE_ACCOUNT_MANAGEMENT];
382
383   NSArray* subviews = [[[controller() window] contentView] subviews];
384   EXPECT_EQ(1U, [subviews count]);
385   subviews = [[subviews objectAtIndex:0] subviews];
386
387   // There should be one active card, one accounts container, two separators
388   // and one option buttons view.
389   EXPECT_EQ(5U, [subviews count]);
390
391   // There should be two buttons in the option buttons view.
392   NSArray* buttonSubviews = [[subviews objectAtIndex:0] subviews];
393   const SEL buttonSelectors[] = { @selector(showUserManager:),
394                                   @selector(lockProfile:) };
395   EXPECT_EQ(2U, [buttonSubviews count]);
396   for (NSUInteger i = 0; i < [buttonSubviews count]; ++i) {
397     NSButton* button = static_cast<NSButton*>([buttonSubviews objectAtIndex:i]);
398     EXPECT_EQ(buttonSelectors[i], [button action]);
399     EXPECT_EQ(controller(), [button target]);
400   }
401
402   // There should be a separator.
403   EXPECT_TRUE([[subviews objectAtIndex:1] isKindOfClass:[NSBox class]]);
404
405   // In the accounts view, there should be the account list container
406   // accounts and one "add accounts" button.
407   NSArray* accountsSubviews = [[subviews objectAtIndex:2] subviews];
408   EXPECT_EQ(2U, [accountsSubviews count]);
409
410   NSButton* addAccountsButton =
411       static_cast<NSButton*>([accountsSubviews objectAtIndex:0]);
412   EXPECT_EQ(@selector(addAccount:), [addAccountsButton action]);
413   EXPECT_EQ(controller(), [addAccountsButton target]);
414
415   // There should be two accounts in the account list container.
416   NSArray* accountsListSubviews = [[accountsSubviews objectAtIndex:1] subviews];
417   EXPECT_EQ(2U, [accountsListSubviews count]);
418
419   NSButton* genericAccount =
420       static_cast<NSButton*>([accountsListSubviews objectAtIndex:0]);
421   NSButton* genericAccountDelete =
422       static_cast<NSButton*>([[genericAccount subviews] objectAtIndex:0]);
423   EXPECT_EQ(@selector(showAccountRemovalView:), [genericAccountDelete action]);
424   EXPECT_EQ(controller(), [genericAccountDelete target]);
425   EXPECT_NE(-1, [genericAccountDelete tag]);
426
427   // Primary accounts are always last.
428   NSButton* primaryAccount =
429       static_cast<NSButton*>([accountsListSubviews objectAtIndex:1]);
430   NSButton* primaryAccountDelete =
431       static_cast<NSButton*>([[primaryAccount subviews] objectAtIndex:0]);
432   EXPECT_EQ(@selector(showAccountRemovalView:), [primaryAccountDelete action]);
433   EXPECT_EQ(controller(), [primaryAccountDelete target]);
434   EXPECT_EQ(-1, [primaryAccountDelete tag]);
435
436   // There should be another separator.
437   EXPECT_TRUE([[subviews objectAtIndex:3] isKindOfClass:[NSBox class]]);
438
439   // There should be the profile avatar, name and a "hide accounts" link
440   // container in the active card view.
441   NSArray* activeCardSubviews = [[subviews objectAtIndex:4] subviews];
442   EXPECT_EQ(3U, [activeCardSubviews count]);
443
444   // Profile icon.
445   NSView* activeProfileImage = [activeCardSubviews objectAtIndex:2];
446   EXPECT_TRUE([activeProfileImage isKindOfClass:[NSImageView class]]);
447
448   // Profile name.
449   NSView* activeProfileName = [activeCardSubviews objectAtIndex:1];
450   EXPECT_TRUE([activeProfileName isKindOfClass:[NSButton class]]);
451   EXPECT_EQ(menu()->GetItemAt(0).name, base::SysNSStringToUTF16(
452       [static_cast<NSButton*>(activeProfileName) title]));
453
454   // Profile links. This is a local profile, so there should be a signin button.
455   NSArray* linksSubviews = [[activeCardSubviews objectAtIndex:0] subviews];
456   EXPECT_EQ(1U, [linksSubviews count]);
457   NSButton* link = static_cast<NSButton*>([linksSubviews objectAtIndex:0]);
458   EXPECT_EQ(@selector(hideAccountManagement:), [link action]);
459   EXPECT_EQ(controller(), [link target]);
460 }