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.
5 #include "chrome/browser/ui/sync/profile_signin_confirmation_helper.h"
7 #include "base/basictypes.h"
9 #include "base/bind_helpers.h"
10 #include "base/callback.h"
11 #include "base/command_line.h"
12 #include "base/compiler_specific.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/message_loop/message_loop.h"
15 #include "base/prefs/pref_notifier_impl.h"
16 #include "base/prefs/pref_service.h"
17 #include "base/prefs/testing_pref_service.h"
18 #include "base/run_loop.h"
19 #include "base/strings/string16.h"
20 #include "base/strings/string_util.h"
21 #include "base/strings/utf_string_conversions.h"
22 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
23 #include "chrome/browser/history/history_service_factory.h"
24 #include "chrome/browser/prefs/browser_prefs.h"
25 #include "chrome/test/base/testing_profile.h"
26 #include "components/bookmarks/browser/bookmark_model.h"
27 #include "components/bookmarks/test/bookmark_test_helpers.h"
28 #include "components/history/core/browser/history_service.h"
29 #include "components/pref_registry/pref_registry_syncable.h"
30 #include "components/syncable_prefs/testing_pref_service_syncable.h"
31 #include "content/public/test/test_browser_thread_bundle.h"
32 #include "content/public/test/test_utils.h"
33 #include "testing/gmock/include/gmock/gmock.h"
34 #include "testing/gtest/include/gtest/gtest.h"
36 #if defined(OS_CHROMEOS)
37 #include "chrome/browser/chromeos/login/users/scoped_test_user_manager.h"
38 #include "chrome/browser/chromeos/settings/cros_settings.h"
39 #include "chrome/browser/chromeos/settings/device_settings_service.h"
42 #if defined(ENABLE_EXTENSIONS)
43 #include "chrome/browser/extensions/extension_service.h"
44 #include "chrome/browser/extensions/test_extension_system.h"
45 #include "chrome/common/extensions/extension_constants.h"
46 #include "extensions/browser/extension_prefs.h"
47 #include "extensions/common/constants.h"
48 #include "extensions/common/extension.h"
49 #include "extensions/common/manifest_constants.h"
50 #include "extensions/common/permissions/permission_set.h"
53 using bookmarks::BookmarkModel
;
58 void GetValueAndQuit(T
* result
, const base::Closure
& quit
, T actual
) {
65 const base::Callback
<void(const base::Callback
<void(T
)>&)>& callback
) {
68 callback
.Run(base::Bind(&GetValueAndQuit
<T
>, &result
, loop
.QuitClosure()));
73 // A pref store that can have its read_error property changed for testing.
74 class TestingPrefStoreWithCustomReadError
: public TestingPrefStore
{
76 TestingPrefStoreWithCustomReadError()
77 : read_error_(PersistentPrefStore::PREF_READ_ERROR_NO_FILE
) {
78 // By default the profile is "new" (NO_FILE means that the profile
79 // wasn't found on disk, so it was created).
81 PrefReadError
GetReadError() const override
{ return read_error_
; }
82 bool IsInitializationComplete() const override
{ return true; }
83 void set_read_error(PrefReadError read_error
) {
84 read_error_
= read_error
;
87 ~TestingPrefStoreWithCustomReadError() override
{}
88 PrefReadError read_error_
;
91 #if defined(ENABLE_EXTENSIONS)
93 const base::FilePath::CharType kExtensionFilePath
[] =
94 FILE_PATH_LITERAL("c:\\foo");
95 #elif defined(OS_POSIX)
96 const base::FilePath::CharType kExtensionFilePath
[] =
97 FILE_PATH_LITERAL("/oo");
100 static scoped_refptr
<extensions::Extension
> CreateExtension(
101 const std::string
& name
,
102 const std::string
& id
,
103 extensions::Manifest::Location location
) {
104 base::DictionaryValue manifest
;
105 manifest
.SetString(extensions::manifest_keys::kVersion
, "1.0.0.0");
106 manifest
.SetString(extensions::manifest_keys::kName
, name
);
108 scoped_refptr
<extensions::Extension
> extension
=
109 extensions::Extension::Create(
110 base::FilePath(kExtensionFilePath
).AppendASCII(name
),
113 extensions::Extension::NO_FLAGS
,
122 class ProfileSigninConfirmationHelperTest
: public testing::Test
{
124 ProfileSigninConfirmationHelperTest()
129 void SetUp() override
{
130 // Create the profile.
131 TestingProfile::Builder builder
;
132 user_prefs_
= new TestingPrefStoreWithCustomReadError
;
133 syncable_prefs::TestingPrefServiceSyncable
* pref_service
=
134 new syncable_prefs::TestingPrefServiceSyncable(
135 new TestingPrefStore(), user_prefs_
, new TestingPrefStore(),
136 new user_prefs::PrefRegistrySyncable(), new PrefNotifierImpl());
137 chrome::RegisterUserProfilePrefs(pref_service
->registry());
138 builder
.SetPrefService(
139 make_scoped_ptr
<syncable_prefs::PrefServiceSyncable
>(pref_service
));
140 profile_
= builder
.Build();
142 // Initialize the services we check.
143 profile_
->CreateBookmarkModel(true);
144 model_
= BookmarkModelFactory::GetForProfile(profile_
.get());
145 bookmarks::test::WaitForBookmarkModelToLoad(model_
);
146 ASSERT_TRUE(profile_
->CreateHistoryService(true, false));
147 #if defined(ENABLE_EXTENSIONS)
148 extensions::TestExtensionSystem
* system
=
149 static_cast<extensions::TestExtensionSystem
*>(
150 extensions::ExtensionSystem::Get(profile_
.get()));
151 base::CommandLine
command_line(base::CommandLine::NO_PROGRAM
);
152 system
->CreateExtensionService(&command_line
,
153 base::FilePath(kExtensionFilePath
),
158 void TearDown() override
{
159 // TestExtensionSystem uses DeleteSoon, so we need to delete the profile
160 // and then run the message queue to clean up.
162 base::RunLoop().RunUntilIdle();
166 content::TestBrowserThreadBundle thread_bundle_
;
167 scoped_ptr
<TestingProfile
> profile_
;
168 TestingPrefStoreWithCustomReadError
* user_prefs_
;
169 BookmarkModel
* model_
;
171 #if defined OS_CHROMEOS
172 chromeos::ScopedTestDeviceSettingsService test_device_settings_service_
;
173 chromeos::ScopedTestCrosSettings test_cros_settings_
;
174 chromeos::ScopedTestUserManager test_user_manager_
;
178 // http://crbug.com/393149
179 TEST_F(ProfileSigninConfirmationHelperTest
, DISABLED_DoNotPromptForNewProfile
) {
180 // Profile is new and there's no profile data.
184 &ui::CheckShouldPromptForNewProfile
,
188 TEST_F(ProfileSigninConfirmationHelperTest
, PromptForNewProfile_Bookmarks
) {
191 // Profile is new but has bookmarks.
192 model_
->AddURL(model_
->bookmark_bar_node(), 0,
193 base::string16(base::ASCIIToUTF16("foo")),
194 GURL("http://foo.com"));
198 &ui::CheckShouldPromptForNewProfile
,
202 #if defined(ENABLE_EXTENSIONS)
203 TEST_F(ProfileSigninConfirmationHelperTest
, PromptForNewProfile_Extensions
) {
204 ExtensionService
* extensions
=
205 extensions::ExtensionSystem::Get(profile_
.get())->extension_service();
206 ASSERT_TRUE(extensions
);
208 // Profile is new but has synced extensions.
210 // (The web store doesn't count.)
211 scoped_refptr
<extensions::Extension
> webstore
=
212 CreateExtension("web store",
213 extensions::kWebStoreAppId
,
214 extensions::Manifest::COMPONENT
);
215 extensions::ExtensionPrefs::Get(profile_
.get())->AddGrantedPermissions(
216 webstore
->id(), make_scoped_refptr(new extensions::PermissionSet
).get());
217 extensions
->AddExtension(webstore
.get());
218 EXPECT_FALSE(GetCallbackResult(
219 base::Bind(&ui::CheckShouldPromptForNewProfile
, profile_
.get())));
221 scoped_refptr
<extensions::Extension
> extension
=
222 CreateExtension("foo", std::string(), extensions::Manifest::INTERNAL
);
223 extensions::ExtensionPrefs::Get(profile_
.get())->AddGrantedPermissions(
224 extension
->id(), make_scoped_refptr(new extensions::PermissionSet
).get());
225 extensions
->AddExtension(extension
.get());
226 EXPECT_TRUE(GetCallbackResult(
227 base::Bind(&ui::CheckShouldPromptForNewProfile
, profile_
.get())));
231 // http://crbug.com/393149
232 TEST_F(ProfileSigninConfirmationHelperTest
,
233 DISABLED_PromptForNewProfile_History
) {
234 history::HistoryService
* history
= HistoryServiceFactory::GetForProfile(
235 profile_
.get(), ServiceAccessType::EXPLICIT_ACCESS
);
236 ASSERT_TRUE(history
);
238 // Profile is new but has more than $(kHistoryEntriesBeforeNewProfilePrompt)
241 for (int i
= 0; i
< 10; i
++) {
242 base::snprintf(buf
, arraysize(buf
), "http://foo.com/%d", i
);
244 GURL(std::string(buf
)), base::Time::Now(), NULL
, 1,
245 GURL(), history::RedirectList(), ui::PAGE_TRANSITION_LINK
,
246 history::SOURCE_BROWSED
, false);
251 &ui::CheckShouldPromptForNewProfile
,
255 // http://crbug.com/393149
256 TEST_F(ProfileSigninConfirmationHelperTest
,
257 DISABLED_PromptForNewProfile_TypedURLs
) {
258 history::HistoryService
* history
= HistoryServiceFactory::GetForProfile(
259 profile_
.get(), ServiceAccessType::EXPLICIT_ACCESS
);
260 ASSERT_TRUE(history
);
262 // Profile is new but has a typed URL.
264 GURL("http://example.com"), base::Time::Now(), NULL
, 1,
265 GURL(), history::RedirectList(), ui::PAGE_TRANSITION_TYPED
,
266 history::SOURCE_BROWSED
, false);
270 &ui::CheckShouldPromptForNewProfile
,
274 TEST_F(ProfileSigninConfirmationHelperTest
, PromptForNewProfile_Restarted
) {
275 // Browser has been shut down since profile was created.
276 user_prefs_
->set_read_error(PersistentPrefStore::PREF_READ_ERROR_NONE
);
280 &ui::CheckShouldPromptForNewProfile
,