[Metrics] Make MetricsStateManager take a callback param to check if UMA is enabled.
[chromium-blink-merge.git] / chrome / browser / ui / cocoa / profiles / profile_menu_controller_unittest.mm
blob7f62487a0aa6df2a7b50d00e27d9c1241c14e50a
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_menu_controller.h"
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"
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   }
33   virtual void SetUp() {
34     CocoaProfileTest::SetUp();
35     ASSERT_TRUE(profile());
37     // Spin the runloop so |-initializeMenu| gets called.
38     chrome::testing::NSRunLoopRunAllPending();
39   }
41   void TestBottomItems() {
42     NSMenu* menu = [controller() menu];
43     NSInteger count = [menu numberOfItems];
45     ASSERT_GE(count, 4);
47     NSMenuItem* item = [menu itemAtIndex:count - 4];
48     EXPECT_TRUE([item isSeparatorItem]);
50     item = [menu itemAtIndex:count - 3];
51     EXPECT_EQ(@selector(editProfile:), [item action]);
53     item = [menu itemAtIndex:count - 2];
54     EXPECT_TRUE([item isSeparatorItem]);
56     item = [menu itemAtIndex:count - 1];
57     EXPECT_EQ(@selector(newProfile:), [item action]);
58   }
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   }
72   ProfileMenuController* controller() { return controller_.get(); }
74   NSMenuItem* menu_item() { return item_.get(); }
76  private:
77   base::scoped_nsobject<NSMenuItem> item_;
78   base::scoped_nsobject<ProfileMenuController> controller_;
81 TEST_F(ProfileMenuControllerTest, InitializeMenu) {
82   NSMenu* menu = [controller() menu];
83   // <sep>, Edit, <sep>, New.
84   ASSERT_EQ(4, [menu numberOfItems]);
86   TestBottomItems();
88   EXPECT_TRUE([menu_item() isHidden]);
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]);
101 TEST_F(ProfileMenuControllerTest, RebuildMenu) {
102   NSMenu* menu = [controller() menu];
103   EXPECT_EQ(4, [menu numberOfItems]);
105   EXPECT_TRUE([menu_item() isHidden]);
107   // Create some more profiles on the manager.
108   TestingProfileManager* manager = testing_profile_manager();
109   manager->CreateTestingProfile("Profile 2");
110   manager->CreateTestingProfile("Profile 3");
112   // Verify that the menu got rebuilt.
113   ASSERT_EQ(7, [menu numberOfItems]);
115   NSMenuItem* item = [menu itemAtIndex:0];
116   EXPECT_EQ(@selector(switchToProfileFromMenu:), [item action]);
118   item = [menu itemAtIndex:1];
119   EXPECT_EQ(@selector(switchToProfileFromMenu:), [item action]);
121   item = [menu itemAtIndex:2];
122   EXPECT_EQ(@selector(switchToProfileFromMenu:), [item action]);
124   TestBottomItems();
126   EXPECT_FALSE([menu_item() isHidden]);
129 TEST_F(ProfileMenuControllerTest, InsertItems) {
130   base::scoped_nsobject<NSMenu> menu([[NSMenu alloc] initWithTitle:@""]);
131   ASSERT_EQ(0, [menu numberOfItems]);
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];
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];
149   // Create one more profile on the manager.
150   TestingProfileManager* manager = testing_profile_manager();
151   manager->CreateTestingProfile("Profile 2");
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]);
160   NSMenuItem* item = [menu itemAtIndex:0];
161   EXPECT_EQ(@selector(switchToProfileFromMenu:), [item action]);
163   item = [menu itemAtIndex:1];
164   EXPECT_EQ(@selector(switchToProfileFromMenu:), [item action]);
165   [menu removeAllItems];
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]);
175   // First item is a label item.
176   item = [menu itemAtIndex:0];
177   EXPECT_FALSE([item isEnabled]);
179   item = [menu itemAtIndex:1];
180   EXPECT_EQ(@selector(switchToProfileFromDock:), [item action]);
182   item = [menu itemAtIndex:2];
183   EXPECT_EQ(@selector(switchToProfileFromDock:), [item action]);
186 TEST_F(ProfileMenuControllerTest, InitialActiveBrowser) {
187   [controller() activeBrowserChangedTo:NULL];
188   VerifyProfileNamedIsActive(l10n_util::GetNSString(IDS_DEFAULT_PROFILE_NAME),
189                              __LINE__);
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]);
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__);
209   // Close the browser and make sure it's still active.
210   p2_browser.reset();
211   VerifyProfileNamedIsActive(@"Profile 2", __LINE__);
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__);
220   p3_browser.reset();
221   VerifyProfileNamedIsActive(@"Profile 3", __LINE__);
224 TEST_F(ProfileMenuControllerTest, DeleteActiveProfile) {
225   TestingProfileManager* manager = testing_profile_manager();
227   manager->CreateTestingProfile("Profile 2");
228   TestingProfile* profile3 = manager->CreateTestingProfile("Profile 3");
229   ASSERT_EQ(3U, manager->profile_manager()->GetNumberOfProfiles());
231   const base::FilePath profile3_path = profile3->GetPath();
232   manager->DeleteTestingProfile("Profile 3");
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());
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);
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());
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]);
264   item = [menu itemAtIndex:1];
265   ASSERT_EQ(@selector(switchToProfileFromMenu:), [item action]);
266   EXPECT_TRUE([controller() validateMenuItem:item]);
268   item = [menu itemAtIndex:5];
269   ASSERT_EQ(@selector(newProfile:), [item action]);
270   EXPECT_TRUE([controller() validateMenuItem:item]);
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());
279   item = [menu itemAtIndex:0];
280   ASSERT_EQ(@selector(switchToProfileFromMenu:), [item action]);
281   EXPECT_FALSE([controller() validateMenuItem:item]);
283   item = [menu itemAtIndex:1];
284   ASSERT_EQ(@selector(switchToProfileFromMenu:), [item action]);
285   EXPECT_TRUE([controller() validateMenuItem:item]);
287   item = [menu itemAtIndex:5];
288   ASSERT_EQ(@selector(newProfile:), [item action]);
289   EXPECT_FALSE([controller() validateMenuItem:item]);