Upstream version 7.35.144.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / cocoa / profile_menu_controller_unittest.mm
1 // Copyright (c) 2011 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/profile_menu_controller.h"
6
7 #include "base/mac/scoped_nsobject.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "base/threading/thread_restrictions.h"
10 #include "chrome/browser/browser_process.h"
11 #include "chrome/browser/prefs/pref_service_syncable.h"
12 #include "chrome/browser/profiles/profile_manager.h"
13 #include "chrome/browser/ui/browser_list.h"
14 #include "chrome/browser/ui/cocoa/cocoa_profile_test.h"
15 #include "chrome/browser/ui/cocoa/run_loop_testing.h"
16 #include "chrome/common/pref_names.h"
17 #include "chrome/test/base/testing_profile.h"
18 #include "chrome/test/base/test_browser_window.h"
19 #include "grit/generated_resources.h"
20 #include "testing/gtest_mac.h"
21 #include "ui/base/l10n/l10n_util_mac.h"
22
23 class ProfileMenuControllerTest : public CocoaProfileTest {
24  public:
25   ProfileMenuControllerTest() {
26     item_.reset([[NSMenuItem alloc] initWithTitle:@"Users"
27                                            action:nil
28                                     keyEquivalent:@""]);
29     controller_.reset(
30         [[ProfileMenuController alloc] initWithMainMenuItem:item_]);
31   }
32
33   virtual void SetUp() {
34     CocoaProfileTest::SetUp();
35     ASSERT_TRUE(profile());
36
37     // Spin the runloop so |-initializeMenu| gets called.
38     chrome::testing::NSRunLoopRunAllPending();
39   }
40
41   void TestBottomItems() {
42     NSMenu* menu = [controller() menu];
43     NSInteger count = [menu numberOfItems];
44
45     ASSERT_GE(count, 4);
46
47     NSMenuItem* item = [menu itemAtIndex:count - 4];
48     EXPECT_TRUE([item isSeparatorItem]);
49
50     item = [menu itemAtIndex:count - 3];
51     EXPECT_EQ(@selector(editProfile:), [item action]);
52
53     item = [menu itemAtIndex:count - 2];
54     EXPECT_TRUE([item isSeparatorItem]);
55
56     item = [menu itemAtIndex:count - 1];
57     EXPECT_EQ(@selector(newProfile:), [item action]);
58   }
59
60   void VerifyProfileNamedIsActive(NSString* title, int line) {
61     for (NSMenuItem* item in [[controller() menu] itemArray]) {
62       if ([[item title] isEqualToString:title]) {
63         EXPECT_EQ(NSOnState, [item state]) << [[item title] UTF8String]
64           << " (from line " << line << ")";
65       } else {
66         EXPECT_EQ(NSOffState, [item state]) << [[item title] UTF8String]
67           << " (from line " << line << ")";
68       }
69     }
70   }
71
72   ProfileMenuController* controller() { return controller_.get(); }
73
74   NSMenuItem* menu_item() { return item_.get(); }
75
76  private:
77   base::scoped_nsobject<NSMenuItem> item_;
78   base::scoped_nsobject<ProfileMenuController> controller_;
79 };
80
81 TEST_F(ProfileMenuControllerTest, InitializeMenu) {
82   NSMenu* menu = [controller() menu];
83   // <sep>, Edit, <sep>, New.
84   ASSERT_EQ(4, [menu numberOfItems]);
85
86   TestBottomItems();
87
88   EXPECT_TRUE([menu_item() isHidden]);
89 }
90
91 TEST_F(ProfileMenuControllerTest, CreateItemWithTitle) {
92   NSMenuItem* item =
93       [controller() createItemWithTitle:@"Title"
94                                  action:@selector(someSelector:)];
95   EXPECT_NSEQ(@"Title", [item title]);
96   EXPECT_EQ(controller(), [item target]);
97   EXPECT_EQ(@selector(someSelector:), [item action]);
98   EXPECT_NSEQ(@"", [item keyEquivalent]);
99 }
100
101 TEST_F(ProfileMenuControllerTest, RebuildMenu) {
102   NSMenu* menu = [controller() menu];
103   EXPECT_EQ(4, [menu numberOfItems]);
104
105   EXPECT_TRUE([menu_item() isHidden]);
106
107   // Create some more profiles on the manager.
108   TestingProfileManager* manager = testing_profile_manager();
109   manager->CreateTestingProfile("Profile 2");
110   manager->CreateTestingProfile("Profile 3");
111
112   // Verify that the menu got rebuilt.
113   ASSERT_EQ(7, [menu numberOfItems]);
114
115   NSMenuItem* item = [menu itemAtIndex:0];
116   EXPECT_EQ(@selector(switchToProfileFromMenu:), [item action]);
117
118   item = [menu itemAtIndex:1];
119   EXPECT_EQ(@selector(switchToProfileFromMenu:), [item action]);
120
121   item = [menu itemAtIndex:2];
122   EXPECT_EQ(@selector(switchToProfileFromMenu:), [item action]);
123
124   TestBottomItems();
125
126   EXPECT_FALSE([menu_item() isHidden]);
127 }
128
129 TEST_F(ProfileMenuControllerTest, InsertItems) {
130   base::scoped_nsobject<NSMenu> menu([[NSMenu alloc] initWithTitle:@""]);
131   ASSERT_EQ(0, [menu numberOfItems]);
132
133   // With only one profile, insertItems should be a no-op.
134   BOOL result = [controller() insertItemsIntoMenu:menu
135                                          atOffset:0
136                                          fromDock:NO];
137   EXPECT_FALSE(result);
138   EXPECT_EQ(0, [menu numberOfItems]);
139   [menu removeAllItems];
140
141   // Same for use in building the dock menu.
142   result = [controller() insertItemsIntoMenu:menu
143                                     atOffset:0
144                                     fromDock:YES];
145   EXPECT_FALSE(result);
146   EXPECT_EQ(0, [menu numberOfItems]);
147   [menu removeAllItems];
148
149   // Create one more profile on the manager.
150   TestingProfileManager* manager = testing_profile_manager();
151   manager->CreateTestingProfile("Profile 2");
152
153   // With more than one profile, insertItems should return YES.
154   result = [controller() insertItemsIntoMenu:menu
155                                     atOffset:0
156                                     fromDock:NO];
157   EXPECT_TRUE(result);
158   ASSERT_EQ(2, [menu numberOfItems]);
159
160   NSMenuItem* item = [menu itemAtIndex:0];
161   EXPECT_EQ(@selector(switchToProfileFromMenu:), [item action]);
162
163   item = [menu itemAtIndex:1];
164   EXPECT_EQ(@selector(switchToProfileFromMenu:), [item action]);
165   [menu removeAllItems];
166
167   // And for the dock, the selector should be different and there should be a
168   // header item.
169   result = [controller() insertItemsIntoMenu:menu
170                                     atOffset:0
171                                     fromDock:YES];
172   EXPECT_TRUE(result);
173   ASSERT_EQ(3, [menu numberOfItems]);
174
175   // First item is a label item.
176   item = [menu itemAtIndex:0];
177   EXPECT_FALSE([item isEnabled]);
178
179   item = [menu itemAtIndex:1];
180   EXPECT_EQ(@selector(switchToProfileFromDock:), [item action]);
181
182   item = [menu itemAtIndex:2];
183   EXPECT_EQ(@selector(switchToProfileFromDock:), [item action]);
184 }
185
186 TEST_F(ProfileMenuControllerTest, InitialActiveBrowser) {
187   [controller() activeBrowserChangedTo:NULL];
188   VerifyProfileNamedIsActive(l10n_util::GetNSString(IDS_DEFAULT_PROFILE_NAME),
189                              __LINE__);
190 }
191
192 // Note: BrowserList::SetLastActive() is typically called as part of
193 // BrowserWindow::Show() and when a Browser becomes active. We don't need a full
194 // BrowserWindow, so it is called manually.
195 TEST_F(ProfileMenuControllerTest, SetActiveAndRemove) {
196   NSMenu* menu = [controller() menu];
197   TestingProfileManager* manager = testing_profile_manager();
198   TestingProfile* profile2 = manager->CreateTestingProfile("Profile 2");
199   TestingProfile* profile3 = manager->CreateTestingProfile("Profile 3");
200   ASSERT_EQ(7, [menu numberOfItems]);
201
202   // Create a browser and "show" it.
203   Browser::CreateParams profile2_params(profile2, chrome::GetActiveDesktop());
204   scoped_ptr<Browser> p2_browser(
205       chrome::CreateBrowserWithTestWindowForParams(&profile2_params));
206   BrowserList::SetLastActive(p2_browser.get());
207   VerifyProfileNamedIsActive(@"Profile 2", __LINE__);
208
209   // Close the browser and make sure it's still active.
210   p2_browser.reset();
211   VerifyProfileNamedIsActive(@"Profile 2", __LINE__);
212
213   // Open a new browser and make sure it takes effect.
214   Browser::CreateParams profile3_params(profile3, chrome::GetActiveDesktop());
215   scoped_ptr<Browser> p3_browser(
216       chrome::CreateBrowserWithTestWindowForParams(&profile3_params));
217   BrowserList::SetLastActive(p3_browser.get());
218   VerifyProfileNamedIsActive(@"Profile 3", __LINE__);
219
220   p3_browser.reset();
221   VerifyProfileNamedIsActive(@"Profile 3", __LINE__);
222 }
223
224 TEST_F(ProfileMenuControllerTest, DeleteActiveProfile) {
225   TestingProfileManager* manager = testing_profile_manager();
226
227   manager->CreateTestingProfile("Profile 2");
228   TestingProfile* profile3 = manager->CreateTestingProfile("Profile 3");
229   ASSERT_EQ(3U, manager->profile_manager()->GetNumberOfProfiles());
230
231   const base::FilePath profile3_path = profile3->GetPath();
232   manager->DeleteTestingProfile("Profile 3");
233
234   // Simulate an unloaded profile by setting the "last used" local state pref
235   // the profile that was just deleted.
236   PrefService* local_state = g_browser_process->local_state();
237   local_state->SetString(prefs::kProfileLastUsed,
238                          profile3_path.BaseName().MaybeAsASCII());
239
240   // Simulate the active browser changing to NULL and ensure a profile doesn't
241   // get created by disallowing IO operations temporarily.
242   const bool io_was_allowed = base::ThreadRestrictions::SetIOAllowed(false);
243   [controller() activeBrowserChangedTo:NULL];
244   base::ThreadRestrictions::SetIOAllowed(io_was_allowed);
245 }
246
247 TEST_F(ProfileMenuControllerTest, ManagedProfile) {
248   TestingProfileManager* manager = testing_profile_manager();
249   TestingProfile* managed_profile =
250       manager->CreateTestingProfile("test1",
251                                     scoped_ptr<PrefServiceSyncable>(),
252                                     base::ASCIIToUTF16("Supervised User"),
253                                     0,
254                                     "TEST_ID",
255                                     TestingProfile::TestingFactories());
256   BrowserList::SetLastActive(browser());
257
258   NSMenu* menu = [controller() menu];
259   ASSERT_EQ(6, [menu numberOfItems]);
260   NSMenuItem* item = [menu itemAtIndex:0];
261   ASSERT_EQ(@selector(switchToProfileFromMenu:), [item action]);
262   EXPECT_TRUE([controller() validateMenuItem:item]);
263
264   item = [menu itemAtIndex:1];
265   ASSERT_EQ(@selector(switchToProfileFromMenu:), [item action]);
266   EXPECT_TRUE([controller() validateMenuItem:item]);
267
268   item = [menu itemAtIndex:5];
269   ASSERT_EQ(@selector(newProfile:), [item action]);
270   EXPECT_TRUE([controller() validateMenuItem:item]);
271
272   // Open a new browser for the managed user and switch to it.
273   Browser::CreateParams managed_profile_params(
274       managed_profile, chrome::HOST_DESKTOP_TYPE_NATIVE);
275   scoped_ptr<Browser> managed_browser(
276       chrome::CreateBrowserWithTestWindowForParams(&managed_profile_params));
277   BrowserList::SetLastActive(managed_browser.get());
278
279   item = [menu itemAtIndex:0];
280   ASSERT_EQ(@selector(switchToProfileFromMenu:), [item action]);
281   EXPECT_FALSE([controller() validateMenuItem:item]);
282
283   item = [menu itemAtIndex:1];
284   ASSERT_EQ(@selector(switchToProfileFromMenu:), [item action]);
285   EXPECT_TRUE([controller() validateMenuItem:item]);
286
287   item = [menu itemAtIndex:5];
288   ASSERT_EQ(@selector(newProfile:), [item action]);
289   EXPECT_FALSE([controller() validateMenuItem:item]);
290 }