Upstream version 7.35.144.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / cocoa / browser / profile_chooser_controller_unittest.mm
1 // Copyright 2013 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/browser/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.h"
19 #include "chrome/browser/signin/signin_manager_factory.h"
20 #include "chrome/browser/ui/browser.h"
21 #include "chrome/browser/ui/cocoa/cocoa_profile_test.h"
22 #include "chrome/common/chrome_switches.h"
23 #include "components/signin/core/browser/profile_oauth2_token_service.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:PROFILE_CHOOSER_VIEW]);
72     [controller_ showWindow:nil];
73   }
74
75   ProfileChooserController* controller() { return controller_; }
76   AvatarMenu* menu() { return menu_; }
77
78  private:
79   base::scoped_nsobject<ProfileChooserController> controller_;
80
81   // Weak; owned by |controller_|.
82   AvatarMenu* menu_;
83
84   DISALLOW_COPY_AND_ASSIGN(ProfileChooserControllerTest);
85 };
86
87 TEST_F(ProfileChooserControllerTest, InitialLayout) {
88   StartProfileChooserController();
89   NSArray* subviews = [[[controller() window] contentView] subviews];
90
91   // Three profiles means we should have one active card, one separator and
92   // one option buttons view.
93   EXPECT_EQ(3U, [subviews count]);
94
95   // For a local profile, there should be one button in the option buttons view.
96   NSArray* buttonSubviews = [[subviews objectAtIndex:0] subviews];
97   EXPECT_EQ(1U, [buttonSubviews count]);
98   NSButton* button = static_cast<NSButton*>([buttonSubviews objectAtIndex:0]);
99   EXPECT_EQ(@selector(showUserManager:), [button action]);
100   EXPECT_EQ(controller(), [button target]);
101
102   // There should be a separator.
103   EXPECT_TRUE([[subviews objectAtIndex:1] isKindOfClass:[NSBox class]]);
104
105   // There should be the profile avatar, name and links container in the active
106   // card view. The links displayed in the container are checked separately.
107   NSArray* activeCardSubviews = [[subviews objectAtIndex:2] subviews];
108   EXPECT_EQ(3U, [activeCardSubviews count]);
109
110   NSView* activeProfileImage = [activeCardSubviews objectAtIndex:0];
111   EXPECT_TRUE([activeProfileImage isKindOfClass:[NSImageView class]]);
112
113   // There are some links in between. The profile name is added last.
114   CGFloat index = [activeCardSubviews count] - 1;
115   NSView* activeProfileName = [activeCardSubviews objectAtIndex:index];
116   EXPECT_TRUE([activeProfileName isKindOfClass:[NSButton class]]);
117   EXPECT_EQ(menu()->GetItemAt(0).name, base::SysNSStringToUTF16(
118       [static_cast<NSButton*>(activeProfileName) title]));
119 }
120
121 TEST_F(ProfileChooserControllerTest, InitialLayoutWithFastUserSwitcher) {
122   // The fast user switcher is only availbale behind a flag.
123   CommandLine::ForCurrentProcess()->AppendSwitch(switches::kFastUserSwitching);
124
125   StartProfileChooserController();
126   NSArray* subviews = [[[controller() window] contentView] subviews];
127
128   // Three profiles means we should have one active card, two "other" profiles,
129   // one separator and one option buttons view.
130   EXPECT_EQ(5U, [subviews count]);
131
132   // For a local profile, there should be one button in the option buttons view.
133   NSArray* buttonSubviews = [[subviews objectAtIndex:0] subviews];
134   EXPECT_EQ(1U, [buttonSubviews count]);
135   NSButton* button = static_cast<NSButton*>([buttonSubviews objectAtIndex:0]);
136   EXPECT_EQ(@selector(showUserManager:), [button action]);
137   EXPECT_EQ(controller(), [button target]);
138
139   // There should be a separator.
140   EXPECT_TRUE([[subviews objectAtIndex:1] isKindOfClass:[NSBox class]]);
141
142   // There should be two "other profiles" items. The items are drawn from the
143   // bottom up, so in the opposite order of those in the AvatarMenu.
144   int profileIndex = 1;
145   for (NSUInteger i = 3; i >= 2; --i) {
146     NSButton* button = static_cast<NSButton*>([subviews objectAtIndex:i]);
147     EXPECT_EQ(menu()->GetItemAt(profileIndex).name,
148               base::SysNSStringToUTF16([button title]));
149     EXPECT_EQ(profileIndex, [button tag]);
150     EXPECT_EQ(@selector(switchToProfile:), [button action]);
151     EXPECT_EQ(controller(), [button target]);
152     profileIndex++;
153   }
154
155   // There should be the profile avatar, name and links container in the active
156   // card view. The links displayed in the container are checked separately.
157   NSArray* activeCardSubviews = [[subviews objectAtIndex:4] subviews];
158   EXPECT_EQ(3U, [activeCardSubviews count]);
159
160   NSView* activeProfileImage = [activeCardSubviews objectAtIndex:0];
161   EXPECT_TRUE([activeProfileImage isKindOfClass:[NSImageView class]]);
162
163   // There are some links in between. The profile name is added last.
164   CGFloat index = [activeCardSubviews count] - 1;
165   NSView* activeProfileName = [activeCardSubviews objectAtIndex:index];
166   EXPECT_TRUE([activeProfileName isKindOfClass:[NSButton class]]);
167   EXPECT_EQ(menu()->GetItemAt(0).name, base::SysNSStringToUTF16(
168       [static_cast<NSButton*>(activeProfileName) title]));
169 }
170
171 TEST_F(ProfileChooserControllerTest, OtherProfilesSortedAlphabetically) {
172   // The fast user switcher is only availbale behind a flag.
173   CommandLine::ForCurrentProcess()->AppendSwitch(switches::kFastUserSwitching);
174
175   // Add two extra profiles, to make sure sorting is alphabetical and not
176   // by order of creation.
177   testing_profile_manager()->
178       CreateTestingProfile("test3", scoped_ptr<PrefServiceSyncable>(),
179                            base::ASCIIToUTF16("New Profile"), 1, std::string(),
180                            TestingProfile::TestingFactories());
181   testing_profile_manager()->
182       CreateTestingProfile("test4", scoped_ptr<PrefServiceSyncable>(),
183                            base::ASCIIToUTF16("Another Test"), 1, std::string(),
184                            TestingProfile::TestingFactories());
185   StartProfileChooserController();
186
187   NSArray* subviews = [[[controller() window] contentView] subviews];
188   NSString* sortedNames[] = { @"Another Test",
189                               @"New Profile",
190                               @"Test 1",
191                               @"Test 2" };
192   // There should be three "other profiles" items, sorted alphabetically.
193   // The "other profiles" start at index 2, after the option buttons and
194   // a separator. We need to iterate through the profiles in the order
195   // displayed in the bubble, which is opposite from the drawn order.
196   int sortedNameIndex = 0;
197   for (NSUInteger i = 5; i >= 2; --i) {
198     NSButton* button = static_cast<NSButton*>([subviews objectAtIndex:i]);
199     EXPECT_TRUE(
200         [[button title] isEqualToString:sortedNames[sortedNameIndex++]]);
201   }
202 }
203
204 TEST_F(ProfileChooserControllerTest, LocalProfileActiveCardLinks) {
205   StartProfileChooserController();
206   NSArray* subviews = [[[controller() window] contentView] subviews];
207   NSArray* activeCardSubviews = [[subviews objectAtIndex:2] subviews];
208   NSArray* activeCardLinks = [[activeCardSubviews objectAtIndex:1] subviews];
209
210   // There should be one "sign in" link.
211   EXPECT_EQ(1U, [activeCardLinks count]);
212   NSButton* signinLink =
213       static_cast<NSButton*>([activeCardLinks objectAtIndex:0]);
214   EXPECT_EQ(@selector(showSigninPage:), [signinLink action]);
215   EXPECT_EQ(controller(), [signinLink target]);
216 }
217
218 TEST_F(ProfileChooserControllerTest, SignedInProfileActiveCardLinks) {
219   // Sign in the first profile.
220   ProfileInfoCache* cache = testing_profile_manager()->profile_info_cache();
221   cache->SetUserNameOfProfileAtIndex(0, base::ASCIIToUTF16(kEmail));
222
223   StartProfileChooserController();
224   NSArray* subviews = [[[controller() window] contentView] subviews];
225   NSArray* activeCardSubviews = [[subviews objectAtIndex:2] subviews];
226   NSArray* activeCardLinks = [[activeCardSubviews objectAtIndex:1] subviews];
227
228   // There is one link: manage accounts.
229   EXPECT_EQ(1U, [activeCardLinks count]);
230   NSButton* manageAccountsLink =
231       static_cast<NSButton*>([activeCardLinks objectAtIndex:0]);
232   EXPECT_EQ(@selector(showAccountManagement:), [manageAccountsLink action]);
233   EXPECT_EQ(controller(), [manageAccountsLink target]);
234 }
235
236 TEST_F(ProfileChooserControllerTest, AccountManagementLayout) {
237   // Sign in the first profile.
238   ProfileInfoCache* cache = testing_profile_manager()->profile_info_cache();
239   cache->SetUserNameOfProfileAtIndex(0, base::ASCIIToUTF16(kEmail));
240
241   // Set up the signin manager and the OAuth2Tokens.
242   Profile* profile = browser()->profile();
243   SigninManagerFactory::GetForProfile(profile)->
244       SetAuthenticatedUsername(kEmail);
245   ProfileOAuth2TokenServiceFactory::GetForProfile(profile)->
246       UpdateCredentials(kEmail, kLoginToken);
247   ProfileOAuth2TokenServiceFactory::GetForProfile(profile)->
248       UpdateCredentials(kSecondaryEmail, kLoginToken);
249
250   StartProfileChooserController();
251   [controller() initMenuContentsWithView:ACCOUNT_MANAGEMENT_VIEW];
252
253   NSArray* subviews = [[[controller() window] contentView] subviews];
254
255   // There should be one active card, one accounts container, two separators
256   // and one option buttons view.
257   EXPECT_EQ(5U, [subviews count]);
258
259   // There should be two buttons in the option buttons view.
260   NSArray* buttonSubviews = [[subviews objectAtIndex:0] subviews];
261   const SEL buttonSelectors[] = { @selector(showUserManager:),
262                                   @selector(lockProfile:) };
263   EXPECT_EQ(2U, [buttonSubviews count]);
264   for (NSUInteger i = 0; i < [buttonSubviews count]; ++i) {
265     NSButton* button = static_cast<NSButton*>([buttonSubviews objectAtIndex:i]);
266     EXPECT_EQ(buttonSelectors[i], [button action]);
267     EXPECT_EQ(controller(), [button target]);
268   }
269
270   // There should be a separator.
271   EXPECT_TRUE([[subviews objectAtIndex:1] isKindOfClass:[NSBox class]]);
272
273   // In the accounts view, there should be the account list container
274   // accounts and one "add accounts" button.
275   NSArray* accountsSubviews = [[subviews objectAtIndex:2] subviews];
276   EXPECT_EQ(2U, [accountsSubviews count]);
277
278   NSButton* addAccountsButton =
279       static_cast<NSButton*>([accountsSubviews objectAtIndex:0]);
280   EXPECT_EQ(@selector(addAccount:), [addAccountsButton action]);
281   EXPECT_EQ(controller(), [addAccountsButton target]);
282
283   // There should be two accounts in the account list container.
284   NSArray* accountsListSubviews = [[accountsSubviews objectAtIndex:1] subviews];
285   EXPECT_EQ(2U, [accountsListSubviews count]);
286
287   NSButton* genericAccount =
288       static_cast<NSButton*>([accountsListSubviews objectAtIndex:0]);
289   EXPECT_EQ(@selector(removeAccount:), [genericAccount action]);
290   EXPECT_EQ(controller(), [genericAccount target]);
291
292   // Primary accounts are always last and can't be deleted.
293   NSButton* primaryAccount =
294       static_cast<NSButton*>([accountsListSubviews objectAtIndex:1]);
295   EXPECT_EQ(nil, [primaryAccount action]);
296   EXPECT_EQ(nil, [primaryAccount target]);
297
298   // There should be another separator.
299   EXPECT_TRUE([[subviews objectAtIndex:3] isKindOfClass:[NSBox class]]);
300
301   // There should be the profile avatar, name and no links container in the
302   // active card view.
303   NSArray* activeCardSubviews = [[subviews objectAtIndex:4] subviews];
304   EXPECT_EQ(2U, [activeCardSubviews count]);
305
306   NSView* activeProfileImage = [activeCardSubviews objectAtIndex:0];
307   EXPECT_TRUE([activeProfileImage isKindOfClass:[NSImageView class]]);
308
309   NSView* activeProfileName = [activeCardSubviews objectAtIndex:1];
310   EXPECT_TRUE([activeProfileName isKindOfClass:[NSButton class]]);
311   EXPECT_EQ(menu()->GetItemAt(0).name, base::SysNSStringToUTF16(
312       [static_cast<NSButton*>(activeProfileName) title]));
313 }