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. 4 5#include "base/basictypes.h" 6#include "base/bind.h" 7#include "base/bind_helpers.h" 8#include "base/files/file_path.h" 9#include "base/files/file_util.h" 10#include "base/memory/ref_counted.h" 11#include "base/message_loop/message_loop.h" 12#include "base/path_service.h" 13#include "base/values.h" 14#include "chrome/browser/browser_process.h" 15#include "chrome/browser/extensions/api/preferences_private/preferences_private_api.h" 16#include "chrome/browser/extensions/extension_apitest.h" 17#include "chrome/browser/extensions/extension_function_test_utils.h" 18#include "chrome/browser/profiles/profile.h" 19#include "chrome/browser/profiles/profile_manager.h" 20#include "chrome/browser/signin/profile_oauth2_token_service_factory.h" 21#include "chrome/browser/sync/profile_sync_components_factory_mock.h" 22#include "chrome/browser/sync/profile_sync_service.h" 23#include "chrome/browser/sync/profile_sync_service_factory.h" 24#include "chrome/browser/sync/supervised_user_signin_manager_wrapper.h" 25#include "chrome/browser/ui/browser.h" 26#include "chrome/common/chrome_constants.h" 27#include "chrome/common/chrome_paths.h" 28#include "chrome/test/base/testing_profile.h" 29#include "components/bookmarks/common/bookmark_constants.h" 30#include "components/sync_driver/sync_prefs.h" 31#include "content/public/browser/browser_context.h" 32#include "extensions/test/extension_test_message_listener.h" 33 34#if defined(OS_CHROMEOS) 35#include "chromeos/chromeos_switches.h" 36#endif 37 38using extensions::PreferencesPrivateGetSyncCategoriesWithoutPassphraseFunction; 39 40namespace { 41 42class FakeProfileSyncService : public ProfileSyncService { 43 public: 44 explicit FakeProfileSyncService(Profile* profile) 45 : ProfileSyncService( 46 scoped_ptr<ProfileSyncComponentsFactory>( 47 new ProfileSyncComponentsFactoryMock()), 48 profile, 49 make_scoped_ptr<SupervisedUserSigninManagerWrapper>(NULL), 50 ProfileOAuth2TokenServiceFactory::GetForProfile(profile), 51 browser_sync::MANUAL_START), 52 sync_initialized_(true), 53 initialized_state_violation_(false) {} 54 55 virtual ~FakeProfileSyncService() {} 56 57 static KeyedService* BuildFakeProfileSyncService( 58 content::BrowserContext* context) { 59 return new FakeProfileSyncService(static_cast<Profile*>(context)); 60 } 61 62 void set_sync_initialized(bool sync_initialized) { 63 sync_initialized_ = sync_initialized; 64 } 65 66 bool initialized_state_violation() { return initialized_state_violation_; } 67 68 // ProfileSyncService: 69 virtual bool sync_initialized() const OVERRIDE { 70 return sync_initialized_; 71 } 72 73 virtual void AddObserver( 74 ProfileSyncServiceBase::Observer* observer) OVERRIDE { 75 if (sync_initialized_) 76 initialized_state_violation_ = true; 77 // Set sync initialized state to true so the function will run after 78 // OnStateChanged is called. 79 sync_initialized_ = true; 80 base::MessageLoop::current()->PostTask( 81 FROM_HERE, 82 base::Bind(&ProfileSyncServiceBase::Observer::OnStateChanged, 83 base::Unretained(observer))); 84 } 85 86 virtual syncer::ModelTypeSet GetEncryptedDataTypes() const OVERRIDE { 87 if (!sync_initialized_) 88 initialized_state_violation_ = true; 89 syncer::ModelTypeSet type_set; 90 type_set.Put(syncer::AUTOFILL); 91 return type_set; 92 } 93 94 virtual syncer::ModelTypeSet GetPreferredDataTypes() const OVERRIDE { 95 if (!sync_initialized_) 96 initialized_state_violation_ = true; 97 syncer::ModelTypeSet preferred_types = 98 syncer::UserSelectableTypes(); 99 preferred_types.Remove(syncer::TYPED_URLS); 100 return preferred_types; 101 } 102 103 private: 104 bool sync_initialized_; 105 // Set to true if a function is called when sync_initialized is in an 106 // unexpected state. 107 mutable bool initialized_state_violation_; 108 109 DISALLOW_COPY_AND_ASSIGN(FakeProfileSyncService); 110}; 111 112class PreferencesPrivateApiTest : public ExtensionApiTest { 113 public: 114 PreferencesPrivateApiTest() : browser_(NULL), service_(NULL) {} 115 virtual ~PreferencesPrivateApiTest() {} 116 117 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 118#if defined(OS_CHROMEOS) 119 command_line->AppendSwitch( 120 chromeos::switches::kIgnoreUserProfileMappingForTests); 121#endif 122 } 123 124 virtual void SetUpOnMainThread() OVERRIDE { 125 ExtensionApiTest::SetUpOnMainThread(); 126 127 base::FilePath path; 128 PathService::Get(chrome::DIR_USER_DATA, &path); 129 path = path.AppendASCII("test_profile"); 130 if (!base::PathExists(path)) 131 CHECK(base::CreateDirectory(path)); 132 133 Profile* profile = 134 Profile::CreateProfile(path, NULL, Profile::CREATE_MODE_SYNCHRONOUS); 135 sync_driver::SyncPrefs sync_prefs(profile->GetPrefs()); 136 sync_prefs.SetKeepEverythingSynced(false); 137 138 ProfileManager* profile_manager = g_browser_process->profile_manager(); 139 profile_manager->RegisterTestingProfile(profile, true, false); 140 141 service_ = static_cast<FakeProfileSyncService*>( 142 ProfileSyncServiceFactory::GetInstance()->SetTestingFactoryAndUse( 143 profile, &FakeProfileSyncService::BuildFakeProfileSyncService)); 144 145 browser_ = new Browser(Browser::CreateParams( 146 profile, chrome::HOST_DESKTOP_TYPE_NATIVE)); 147 } 148 149 // Calls GetSyncCategoriesWithoutPassphraseFunction and verifies that the 150 // results returned are the expected ones. 151 void TestGetSyncCategoriesWithoutPassphraseFunction(); 152 153 protected: 154 Browser* browser_; 155 FakeProfileSyncService* service_; 156 157 private: 158 DISALLOW_COPY_AND_ASSIGN(PreferencesPrivateApiTest); 159}; 160 161void 162PreferencesPrivateApiTest::TestGetSyncCategoriesWithoutPassphraseFunction() { 163 scoped_refptr<PreferencesPrivateGetSyncCategoriesWithoutPassphraseFunction> 164 function( 165 new PreferencesPrivateGetSyncCategoriesWithoutPassphraseFunction); 166 ASSERT_TRUE(extension_function_test_utils::RunFunction( 167 function.get(), "[]", browser_, extension_function_test_utils::NONE)); 168 EXPECT_FALSE(service_->initialized_state_violation()); 169 170 const base::ListValue* result = function->GetResultList(); 171 EXPECT_EQ(1u, result->GetSize()); 172 173 const base::ListValue* categories = NULL; 174 ASSERT_TRUE(result->GetList(0, &categories)); 175 EXPECT_NE(categories->end(), 176 categories->Find(base::StringValue(bookmarks::kBookmarksFileName))); 177 EXPECT_NE(categories->end(), 178 categories->Find(base::StringValue(chrome::kPreferencesFilename))); 179 EXPECT_EQ(categories->end(), 180 categories->Find(base::StringValue("Autofill"))) << 181 "Encrypted categories should not be present"; 182 EXPECT_EQ(categories->end(), 183 categories->Find(base::StringValue("Typed URLs"))) << 184 "Unsynced categories should not be present"; 185} 186 187IN_PROC_BROWSER_TEST_F(PreferencesPrivateApiTest, 188 GetSyncCategoriesWithoutPassphrase) { 189 TestGetSyncCategoriesWithoutPassphraseFunction(); 190} 191 192// Verifies that we wait for the sync service to be ready before checking 193// encryption status. 194IN_PROC_BROWSER_TEST_F(PreferencesPrivateApiTest, 195 GetSyncCategoriesWithoutPassphraseAsynchronous) { 196 service_->set_sync_initialized(false); 197 TestGetSyncCategoriesWithoutPassphraseFunction(); 198} 199 200} // namespace 201