profile_list_chromeos_unittest.cc revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
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#include <string>
6
7#include "ash/ash_switches.h"
8#include "base/command_line.h"
9#include "base/memory/scoped_ptr.h"
10#include "base/strings/string16.h"
11#include "base/strings/utf_string_conversions.h"
12#include "chrome/browser/chromeos/login/fake_user_manager.h"
13#include "chrome/browser/chromeos/profiles/profile_helper.h"
14#include "chrome/browser/prefs/pref_service_syncable.h"
15#include "chrome/browser/profiles/avatar_menu.h"
16#include "chrome/browser/profiles/avatar_menu_observer.h"
17#include "chrome/browser/profiles/profile_info_cache.h"
18#include "chrome/browser/ui/ash/chrome_shell_delegate.h"
19#include "chrome/common/chrome_constants.h"
20#include "chrome/common/chrome_switches.h"
21#include "chrome/test/base/testing_browser_process.h"
22#include "chrome/test/base/testing_profile_manager.h"
23#include "testing/gtest/include/gtest/gtest.h"
24#include "ui/base/l10n/l10n_util.h"
25
26using base::ASCIIToUTF16;
27
28namespace {
29
30// As defined in /chromeos/dbus/cryptohome_client.cc.
31static const char kUserIdHashSuffix[] = "-hash";
32
33class MockObserver : public AvatarMenuObserver {
34 public:
35  MockObserver() : count_(0) {}
36  virtual ~MockObserver() {}
37
38  virtual void OnAvatarMenuChanged(
39      AvatarMenu* avatar_menu) OVERRIDE {
40    ++count_;
41  }
42
43  int change_count() const { return count_; }
44
45 private:
46  int count_;
47
48  DISALLOW_COPY_AND_ASSIGN(MockObserver);
49};
50
51}  // namespace
52
53namespace chromeos {
54
55class ProfileListChromeOSTest : public testing::Test {
56 public:
57  ProfileListChromeOSTest()
58      : manager_(TestingBrowserProcess::GetGlobal()) {
59  }
60
61  virtual void SetUp() {
62    ASSERT_TRUE(manager_.SetUp());
63
64    // AvatarMenu and multiple profiles works after user logged in.
65    manager_.SetLoggedIn(true);
66
67    // We only instantiate UserMenuModel if multi-profile mode is enabled.
68    CommandLine* cl = CommandLine::ForCurrentProcess();
69    cl->AppendSwitch(switches::kMultiProfiles);
70
71    // Initialize the UserManager singleton to a fresh FakeUserManager instance.
72    user_manager_enabler_.reset(
73        new ScopedUserManagerEnabler(new FakeUserManager));
74  }
75
76  FakeUserManager* GetFakeUserManager() {
77    return static_cast<FakeUserManager*>(UserManager::Get());
78  }
79
80  void AddProfile(base::string16 name, bool log_in) {
81    std::string email_string = base::UTF16ToASCII(name) + "@example.com";
82
83    // Add a user to the fake user manager.
84    GetFakeUserManager()->AddUser(email_string);
85    if (log_in) {
86      GetFakeUserManager()->UserLoggedIn(
87          email_string,
88          email_string + kUserIdHashSuffix,
89          false);
90    }
91
92    // Create a profile for the user.
93    manager()->CreateTestingProfile(
94        chrome::kProfileDirPrefix + email_string + kUserIdHashSuffix,
95        scoped_ptr<PrefServiceSyncable>(),
96        ASCIIToUTF16(email_string), 0, std::string(),
97        TestingProfile::TestingFactories());
98  }
99
100  AvatarMenu* GetAvatarMenu() {
101    // Reset the MockObserver.
102    mock_observer_.reset(new MockObserver());
103    EXPECT_EQ(0, change_count());
104
105    // Reset the menu.
106    avatar_menu_.reset(new AvatarMenu(
107        manager()->profile_info_cache(),
108        mock_observer_.get(),
109        NULL));
110    avatar_menu_->RebuildMenu();
111    EXPECT_EQ(0, change_count());
112    return avatar_menu_.get();
113  }
114
115  void ActiveUserChanged(ProfileHelper* profile_helper,
116                         const std::string& hash) {
117    profile_helper->ActiveUserHashChanged(hash);
118  }
119
120  TestingProfileManager* manager() { return &manager_; }
121
122  int change_count() const { return mock_observer_->change_count(); }
123
124 private:
125  TestingProfileManager manager_;
126  scoped_ptr<MockObserver> mock_observer_;
127  scoped_ptr<ScopedUserManagerEnabler> user_manager_enabler_;
128  scoped_ptr<AvatarMenu> avatar_menu_;
129  ChromeShellDelegate chrome_shell_delegate_;
130
131  DISALLOW_COPY_AND_ASSIGN(ProfileListChromeOSTest);
132};
133
134TEST_F(ProfileListChromeOSTest, InitialCreation) {
135  base::string16 name1(ASCIIToUTF16("p1"));
136
137  AddProfile(name1, true);
138
139  AvatarMenu* menu = GetAvatarMenu();
140
141  ASSERT_EQ(1U, menu->GetNumberOfItems());
142
143  const AvatarMenu::Item& item1 = menu->GetItemAt(0);
144  EXPECT_EQ(0U, item1.menu_index);
145  EXPECT_EQ(name1, item1.name);
146}
147
148TEST_F(ProfileListChromeOSTest, ShowLoggedInUsers) {
149  base::string16 name1(ASCIIToUTF16("p1"));
150  base::string16 name2(ASCIIToUTF16("p2"));
151  base::string16 name3(ASCIIToUTF16("p3"));
152  base::string16 name4(ASCIIToUTF16("p4"));
153
154  AddProfile(name1, true);
155  AddProfile(name2, false);
156  AddProfile(name3, true);
157  AddProfile(name4, false);
158
159  AvatarMenu* menu = GetAvatarMenu();
160
161  ASSERT_EQ(2U, menu->GetNumberOfItems());
162
163  const AvatarMenu::Item& item1 = menu->GetItemAt(0);
164  EXPECT_EQ(0U, item1.menu_index);
165  EXPECT_EQ(name1, item1.name);
166
167  const AvatarMenu::Item& item3 = menu->GetItemAt(1);
168  EXPECT_EQ(1U, item3.menu_index);
169  EXPECT_EQ(name3, item3.name);
170}
171
172TEST_F(ProfileListChromeOSTest, DontShowManagedUsers) {
173  base::string16 name1(ASCIIToUTF16("p1"));
174  base::string16 managed_name(ASCIIToUTF16("p2@example.com"));
175
176  AddProfile(name1, true);
177
178  // Add a managed user profile.
179  ProfileInfoCache* cache = manager()->profile_info_cache();
180  manager()->profile_info_cache()->AddProfileToCache(
181      cache->GetUserDataDir().AppendASCII("p2"), managed_name,
182      base::string16(), 0, "TEST_ID");
183
184  GetFakeUserManager()->AddUser(base::UTF16ToASCII(managed_name));
185
186  AvatarMenu* menu = GetAvatarMenu();
187  ASSERT_EQ(1U, menu->GetNumberOfItems());
188
189  const AvatarMenu::Item& item1 = menu->GetItemAt(0);
190  EXPECT_EQ(0U, item1.menu_index);
191  EXPECT_EQ(name1, item1.name);
192}
193
194TEST_F(ProfileListChromeOSTest, ShowAddProfileLink) {
195  base::string16 name1(ASCIIToUTF16("p1.com"));
196  base::string16 name2(ASCIIToUTF16("p2.com"));
197
198  AddProfile(name1, true);
199  AddProfile(name2, false);
200
201  AvatarMenu* menu = GetAvatarMenu();
202
203  ASSERT_EQ(1U, menu->GetNumberOfItems());
204  EXPECT_TRUE(menu->ShouldShowAddNewProfileLink());
205}
206
207TEST_F(ProfileListChromeOSTest, DontShowAddProfileLink) {
208  base::string16 name1(ASCIIToUTF16("p1.com"));
209  base::string16 name2(ASCIIToUTF16("p2.com"));
210
211  AddProfile(name1, true);
212  AddProfile(name2, true);
213
214  AvatarMenu* menu = GetAvatarMenu();
215
216  ASSERT_EQ(2U, menu->GetNumberOfItems());
217  EXPECT_FALSE(menu->ShouldShowAddNewProfileLink());
218}
219
220TEST_F(ProfileListChromeOSTest, ActiveItem) {
221  base::string16 name1(ASCIIToUTF16("p1.com"));
222  base::string16 name2(ASCIIToUTF16("p2.com"));
223
224  AddProfile(name1, true);
225  AddProfile(name2, true);
226
227  // Initialize ProfileHelper, it will be accessed from GetActiveProfileIndex.
228  std::string email_string = base::UTF16ToASCII(name1) + "@example.com";
229  std::string hash = email_string + kUserIdHashSuffix;
230  ActiveUserChanged(
231      g_browser_process->platform_part()->profile_helper(), hash);
232
233  AvatarMenu* menu = GetAvatarMenu();
234
235  ASSERT_EQ(2U, menu->GetNumberOfItems());
236  // TODO(jeremy): Expand test to verify active profile index other than 0
237  // crbug.com/100871
238  ASSERT_EQ(0U, menu->GetActiveProfileIndex());
239}
240
241TEST_F(ProfileListChromeOSTest, ModifyingNameResortsCorrectly) {
242  base::string16 name1(ASCIIToUTF16("Alpha"));
243  base::string16 name2(ASCIIToUTF16("Beta"));
244  base::string16 newname1(ASCIIToUTF16("Gamma"));
245
246  AddProfile(name1, true);
247  AddProfile(name2, true);
248
249  AvatarMenu* menu = GetAvatarMenu();
250
251  ASSERT_EQ(2U, menu->GetNumberOfItems());
252
253  const AvatarMenu::Item& item1 = menu->GetItemAt(0);
254  EXPECT_EQ(0U, item1.menu_index);
255  EXPECT_EQ(name1, item1.name);
256
257  const AvatarMenu::Item& item2 = menu->GetItemAt(1);
258  EXPECT_EQ(1U, item2.menu_index);
259  EXPECT_EQ(name2, item2.name);
260
261  // Change name of the first profile, to trigger resorting of the profiles:
262  // now the first menu item should be named "beta", and the second be "gamma".
263  GetFakeUserManager()->SaveUserDisplayName(
264      base::UTF16ToASCII(name1) + "@example.com", newname1);
265  manager()->profile_info_cache()->SetNameOfProfileAtIndex(0, newname1);
266
267  const AvatarMenu::Item& item1next = menu->GetItemAt(0);
268  EXPECT_GT(change_count(), 1);
269  EXPECT_EQ(0U, item1next.menu_index);
270  EXPECT_EQ(name2, item1next.name);
271
272  const AvatarMenu::Item& item2next = menu->GetItemAt(1);
273  EXPECT_EQ(1U, item2next.menu_index);
274  EXPECT_EQ(newname1, item2next.name);
275}
276
277TEST_F(ProfileListChromeOSTest, ChangeOnNotify) {
278  base::string16 name1(ASCIIToUTF16("p1.com"));
279  base::string16 name2(ASCIIToUTF16("p2.com"));
280
281  AddProfile(name1, true);
282  AddProfile(name2, true);
283
284  AvatarMenu* menu = GetAvatarMenu();
285  EXPECT_EQ(2U, menu->GetNumberOfItems());
286
287  base::string16 name3(ASCIIToUTF16("p3.com"));
288  AddProfile(name3, true);
289
290  // Four changes happened via the call to CreateTestingProfile: adding the
291  // profile to the cache, setting the user name, rebuilding the list of
292  // profiles after the name change, and changing the avatar.
293  // TODO(michaelpg): Determine why actual change number does not match comment.
294  EXPECT_GE(change_count(), 4);
295  ASSERT_EQ(3U, menu->GetNumberOfItems());
296
297  const AvatarMenu::Item& item1 = menu->GetItemAt(0);
298  EXPECT_EQ(0U, item1.menu_index);
299  EXPECT_EQ(name1, item1.name);
300
301  const AvatarMenu::Item& item2 = menu->GetItemAt(1);
302  EXPECT_EQ(1U, item2.menu_index);
303  EXPECT_EQ(name2, item2.name);
304
305  const AvatarMenu::Item& item3 = menu->GetItemAt(2);
306  EXPECT_EQ(2U, item3.menu_index);
307  EXPECT_EQ(name3, item3.name);
308}
309
310TEST_F(ProfileListChromeOSTest, DontShowAvatarMenu) {
311  // If in the new M-32 UX mode the icon gets shown, the menu will not.
312  base::string16 name1(ASCIIToUTF16("p1"));
313  base::string16 name2(ASCIIToUTF16("p2"));
314
315  AddProfile(name1, true);
316
317  // Should only show avatar menu with multiple users.
318  EXPECT_FALSE(AvatarMenu::ShouldShowAvatarMenu());
319
320  AddProfile(name2, false);
321
322  EXPECT_FALSE(AvatarMenu::ShouldShowAvatarMenu());
323}
324
325}  // namespace chromeos
326